chore(studio): add feature preview for auth security template UI (#39661)

* feature preview logic

* sidebar changes based on feature preview

* singular naming

* minor

* Flip isPlatformOnly for new preview

---------

Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
This commit is contained in:
Danny WhiteandJoshen Lim authored and GitHub committed 2025-10-21 15:18:56 +11:00
1 parent bd2ee0de8a
commit c1681cfcc2
8 files changed
+98 -4

No files matched your search

@@ -1,6 +1,13 @@
import { LOCAL_STORAGE_KEYS } from 'common'
export const FEATURE_PREVIEWS = [
{
key: LOCAL_STORAGE_KEYS.UI_PREVIEW_SECURITY_NOTIFICATIONS,
name: 'Security notification templates',
discussionsUrl: undefined,
isNew: true,
isPlatformOnly: true,
},
{
key: LOCAL_STORAGE_KEYS.UI_PREVIEW_NEW_STORAGE_UI,
name: 'New Storage interface',
@@ -115,6 +115,11 @@ export const useIsNewStorageUIEnabled = () => {
return flags[LOCAL_STORAGE_KEYS.UI_PREVIEW_NEW_STORAGE_UI]
}
export const useIsSecurityNotificationsEnabled = () => {
const { flags } = useFeaturePreviewContext()
return flags[LOCAL_STORAGE_KEYS.UI_PREVIEW_SECURITY_NOTIFICATIONS]
}
export const useFeaturePreviewModal = () => {
const [featurePreviewModal, setFeaturePreviewModal] = useQueryState('featurePreviewModal')
@@ -122,6 +127,7 @@ export const useFeaturePreviewModal = () => {
const advisorRulesEnabled = useFlag('advisorRules')
const isUnifiedLogsPreviewAvailable = useFlag('unifiedLogs')
const isNewStorageUIAvailable = useFlag('storageAnalyticsVector')
const isSecurityNotificationsAvailable = useFlag('securityNotifications')
const selectedFeatureKeyFromQuery = featurePreviewModal?.trim() ?? null
const showFeaturePreviewModal = selectedFeatureKeyFromQuery !== null
@@ -138,11 +144,19 @@ export const useFeaturePreviewModal = () => {
return isUnifiedLogsPreviewAvailable
case 'new-storage-ui':
return isNewStorageUIAvailable
case 'security-notifications':
return isSecurityNotificationsAvailable
default:
return true
}
},
[gitlessBranchingEnabled, advisorRulesEnabled, isUnifiedLogsPreviewAvailable]
[
gitlessBranchingEnabled,
advisorRulesEnabled,
isUnifiedLogsPreviewAvailable,
isNewStorageUIAvailable,
isSecurityNotificationsAvailable,
]
)
const selectedFeatureKey = (
@@ -16,6 +16,7 @@ import { useFeaturePreviewContext, useFeaturePreviewModal } from './FeaturePrevi
import { InlineEditorPreview } from './InlineEditorPreview'
import { NewStorageUIPreview } from './NewStorageUIPreview'
import { UnifiedLogsPreview } from './UnifiedLogsPreview'
import { SecurityNotificationsPreview } from './SecurityNotificationsPreview'
const FEATURE_PREVIEW_KEY_TO_CONTENT: {
[key: string]: ReactNode
@@ -27,6 +28,7 @@ const FEATURE_PREVIEW_KEY_TO_CONTENT: {
[LOCAL_STORAGE_KEYS.UI_PREVIEW_CLS]: <CLSPreview />,
[LOCAL_STORAGE_KEYS.UI_PREVIEW_UNIFIED_LOGS]: <UnifiedLogsPreview />,
[LOCAL_STORAGE_KEYS.UI_PREVIEW_NEW_STORAGE_UI]: <NewStorageUIPreview />,
[LOCAL_STORAGE_KEYS.UI_PREVIEW_SECURITY_NOTIFICATIONS]: <SecurityNotificationsPreview />,
}
const FeaturePreviewModal = () => {
@@ -0,0 +1,46 @@
import Image from 'next/image'
import { useParams } from 'common'
import { InlineLink } from 'components/ui/InlineLink'
import { BASE_PATH } from 'lib/constants'
import { useIsSecurityNotificationsEnabled } from './FeaturePreviewContext'
export const SecurityNotificationsPreview = () => {
const { ref } = useParams()
const isSecurityNotificationsEnabled = useIsSecurityNotificationsEnabled()
return (
<div className="text-sm text-foreground-light">
<Image
alt="Security notifications preview"
src={`${BASE_PATH}/img/previews/security-notifications-preview.png`}
width={1296}
height={900}
className="rounded border mb-4"
/>
<div className="space-y-2 !mt-4">
<p className=" mb-4">
Try out our expanded set of{' '}
<InlineLink
href={`/project/${ref ?? '_'}/auth/${isSecurityNotificationsEnabled ? 'email' : 'templates'}`}
>
email templates
</InlineLink>{' '}
with support for security-related notifications.
</p>
<p className="text-foreground">Enabling this preview will:</p>
<ul className="list-disc pl-6 space-y-1">
<li>Add a dedicated sidebar section for contact methods like email and SMS</li>
<li>Add new email templates for security-related notifications</li>
<li>Move each (existing and new) template into its own dynamic route</li>
</ul>
<p>
These changes are necessary to support incoming security-related notification templates.
Given that the list of our email templates is doubling in size, this change requires some
wider interface changes. Ones that we think make for a clearer experience overall. Win
win!
</p>
</div>
</div>
)
}
@@ -1,20 +1,21 @@
import { useRouter } from 'next/router'
import { PropsWithChildren } from 'react'
import { useParams } from 'common'
import { useFlag, useParams } from 'common'
import { useIsSecurityNotificationsEnabled } from 'components/interfaces/App/FeaturePreview/FeaturePreviewContext'
import { ProductMenu } from 'components/ui/ProductMenu'
import { useAuthConfigPrefetch } from 'data/auth/auth-config-query'
import { useIsFeatureEnabled } from 'hooks/misc/useIsFeatureEnabled'
import { withAuth } from 'hooks/misc/withAuth'
import { ProjectLayout } from '../ProjectLayout/ProjectLayout'
import { generateAuthMenu } from './AuthLayout.utils'
import { useFlag } from 'common'
const AuthProductMenu = () => {
const router = useRouter()
const { ref: projectRef = 'default' } = useParams()
const authenticationShowOverview = useFlag('authOverviewPage')
const authenticationShowSecurityNotifications = useIsSecurityNotificationsEnabled()
const {
authenticationSignInProviders,
@@ -46,6 +47,7 @@ const AuthProductMenu = () => {
authenticationAttackProtection,
authenticationAdvanced,
authenticationShowOverview,
authenticationShowSecurityNotifications,
})}
/>
)
@@ -11,6 +11,7 @@ export const generateAuthMenu = (
authenticationAttackProtection: boolean
authenticationAdvanced: boolean
authenticationShowOverview: boolean
authenticationShowSecurityNotifications: boolean
}
): ProductMenuGroup[] => {
const {
@@ -21,6 +22,7 @@ export const generateAuthMenu = (
authenticationAttackProtection,
authenticationAdvanced,
authenticationShowOverview,
authenticationShowSecurityNotifications,
} = flags ?? {}
return [
@@ -33,6 +35,26 @@ export const generateAuthMenu = (
{ name: 'Users', key: 'users', url: `/project/${ref}/auth/users`, items: [] },
],
},
...(authenticationEmails && authenticationShowSecurityNotifications && IS_PLATFORM
? [
{
title: 'Notifications',
items: [
...(authenticationEmails
? [
{
name: 'Email',
key: 'email',
pages: ['templates', 'smtp'],
url: `/project/${ref}/auth/templates`,
items: [],
},
]
: []),
],
},
]
: []),
{
title: 'Configuration',
items: [
@@ -71,7 +93,7 @@ export const generateAuthMenu = (
},
]
: []),
...(authenticationEmails
...(authenticationEmails && !authenticationShowSecurityNotifications
? [
{
name: 'Emails',
Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

@@ -18,6 +18,7 @@ export const LOCAL_STORAGE_KEYS = {
UI_PREVIEW_BRANCHING_2_0: 'supabase-ui-branching-2-0',
UI_PREVIEW_ADVISOR_RULES: 'supabase-ui-advisor-rules',
UI_PREVIEW_NEW_STORAGE_UI: 'new-storage-ui',
UI_PREVIEW_SECURITY_NOTIFICATIONS: 'security-notifications',
NEW_LAYOUT_NOTICE_ACKNOWLEDGED: 'new-layout-notice-acknowledge',
TABS_INTERFACE_ACKNOWLEDGED: 'tabs-interface-acknowledge',