diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index cd5b82a2b0c84..03b1acdff9463 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -2,7 +2,7 @@ /packages/shared-data/pricing.ts @roryw10 @supabase/billing /packages/shared-data/plans.ts @roryw10 @supabase/billing /packages/common/telemetry-constants.ts @supabase/growth-eng -/packages/pg-meta @supabase/postgres +/packages/pg-meta @supabase/postgres @avallete /apps/studio/ @supabase/Dashboard diff --git a/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreviewContext.tsx b/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreviewContext.tsx index 79351481b7ff4..a127772766f7e 100644 --- a/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreviewContext.tsx +++ b/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreviewContext.tsx @@ -28,10 +28,13 @@ export const useFeaturePreviewContext = () => useContext(FeaturePreviewContext) export const FeaturePreviewContextProvider = ({ children }: PropsWithChildren<{}>) => { const { hasLoaded } = useContext(FeatureFlagContext) + const securityNotificationsFlag = useFlag('securityNotifications') // [Joshen] Similar logic to feature flagging previews, we can use flags to default opt in previews const isDefaultOptIn = (feature: (typeof FEATURE_PREVIEWS)[number]) => { switch (feature.key) { + case LOCAL_STORAGE_KEYS.UI_PREVIEW_SECURITY_NOTIFICATIONS: + return securityNotificationsFlag default: return false } @@ -116,7 +119,6 @@ export const useFeaturePreviewModal = () => { const gitlessBranchingEnabled = useFlag('gitlessBranching') const advisorRulesEnabled = useFlag('advisorRules') const isUnifiedLogsPreviewAvailable = useFlag('unifiedLogs') - const isSecurityNotificationsAvailable = useFlag('securityNotifications') const selectedFeatureKeyFromQuery = featurePreviewModal?.trim() ?? null const showFeaturePreviewModal = selectedFeatureKeyFromQuery !== null @@ -131,18 +133,11 @@ export const useFeaturePreviewModal = () => { return advisorRulesEnabled case 'supabase-ui-preview-unified-logs': return isUnifiedLogsPreviewAvailable - case 'security-notifications': - return isSecurityNotificationsAvailable default: return true } }, - [ - gitlessBranchingEnabled, - advisorRulesEnabled, - isUnifiedLogsPreviewAvailable, - isSecurityNotificationsAvailable, - ] + [gitlessBranchingEnabled, advisorRulesEnabled, isUnifiedLogsPreviewAvailable] ) const selectedFeatureKey = ( diff --git a/apps/studio/components/interfaces/Database/ProtectedSchemaWarning.tsx b/apps/studio/components/interfaces/Database/ProtectedSchemaWarning.tsx index 5ba9d30c22f72..e5735bfbc5147 100644 --- a/apps/studio/components/interfaces/Database/ProtectedSchemaWarning.tsx +++ b/apps/studio/components/interfaces/Database/ProtectedSchemaWarning.tsx @@ -10,7 +10,6 @@ import { DialogSectionSeparator, DialogTitle, DialogTrigger, - cn, } from 'ui' import { INTERNAL_SCHEMAS, useIsProtectedSchema } from 'hooks/useProtectedSchemas' @@ -71,20 +70,17 @@ export const ProtectedSchemaWarning = ({ return ( div>p]:prose [&>div>p]:max-w-full [&>div>p]:!leading-normal', - size === 'sm' ? '[&>div>p]:text-xs' : '[&>div>p]:text-sm' - )} + className="[&_p]:!m-0" > {reason === 'fdw' && fdwType === 'iceberg' ? (

- The {schema} schema is used by Supabase to connect to - analytics buckets and is read-only through the dashboard. + The {schema} schema is used by Supabase to + connect to analytics buckets and is read-only through the dashboard.

) : reason === 'fdw' && fdwType === 's3_vectors' ? (

@@ -94,8 +90,8 @@ export const ProtectedSchemaWarning = ({ ) : ( <>

- The {schema} schema is managed by Supabase and is - read-only through the dashboard. + The {schema} schema is managed by Supabase and + is read-only through the dashboard.

diff --git a/apps/studio/components/interfaces/Database/Tables/TableList.tsx b/apps/studio/components/interfaces/Database/Tables/TableList.tsx index cfaa15e552c09..1a6ef0b3e63d1 100644 --- a/apps/studio/components/interfaces/Database/Tables/TableList.tsx +++ b/apps/studio/components/interfaces/Database/Tables/TableList.tsx @@ -11,7 +11,6 @@ import { MoreVertical, Plus, Search, - Table2, Trash, X, } from 'lucide-react' @@ -24,6 +23,7 @@ import { LOAD_TAB_FROM_CACHE_PARAM } from 'components/grid/SupabaseGrid.utils' import AlertError from 'components/ui/AlertError' import { ButtonTooltip } from 'components/ui/ButtonTooltip' import { DropdownMenuItemTooltip } from 'components/ui/DropdownMenuItemTooltip' +import { EntityTypeIcon } from 'components/ui/EntityTypeIcon' import SchemaSelector from 'components/ui/SchemaSelector' import { GenericSkeletonLoader } from 'components/ui/ShimmeringLoader' import { useDatabasePublicationsQuery } from 'data/database-publications/database-publications-query' @@ -60,7 +60,6 @@ import { Tooltip, TooltipContent, TooltipTrigger, - cn, } from 'ui' import { ProtectedSchemaWarning } from '../ProtectedSchemaWarning' import { formatAllEntities } from './Tables.utils' @@ -206,11 +205,14 @@ export const TableList = ({ isSuccessTables && isSuccessViews && isSuccessMaterializedViews && isSuccessForeignTables const formatTooltipText = (entityType: string) => { - return Object.entries(ENTITY_TYPE) - .find(([, value]) => value === entityType)?.[0] - ?.toLowerCase() - ?.split('_') - ?.join(' ') + const text = + Object.entries(ENTITY_TYPE) + .find(([, value]) => value === entityType)?.[0] + ?.toLowerCase() + ?.split('_') + ?.join(' ') || '' + // Return sentence case (capitalize first letter only) + return text.charAt(0).toUpperCase() + text.slice(1) } return ( @@ -383,40 +385,14 @@ export const TableList = ({ - - {x.type === ENTITY_TYPE.TABLE ? ( - - ) : x.type === ENTITY_TYPE.VIEW ? ( - - ) : ( -
- {Object.entries(ENTITY_TYPE) - .find(([, value]) => value === x.type)?.[0]?.[0] - ?.toUpperCase()} -
- )} + + {/* [Alaister]: EntityTypeIcon supports PARTITIONED_TABLE, but formatAllEntities + doesn't distinguish between tables and partitioned tables yet. + Once the endpoint/formatAllEntities is updated to include partitioned tables, + EntityTypeIcon will automatically style them correctly. */} + - + {formatTooltipText(x.type)}
diff --git a/apps/studio/components/layouts/TableEditorLayout/EntityListItem.tsx b/apps/studio/components/layouts/TableEditorLayout/EntityListItem.tsx index 06fc58a7840d1..9d34cf2652bf1 100644 --- a/apps/studio/components/layouts/TableEditorLayout/EntityListItem.tsx +++ b/apps/studio/components/layouts/TableEditorLayout/EntityListItem.tsx @@ -122,11 +122,14 @@ const EntityListItem = ({ ).hasLint const formatTooltipText = (entityType: string) => { - return Object.entries(ENTITY_TYPE) - .find(([, value]) => value === entityType)?.[0] - ?.toLowerCase() - ?.split('_') - ?.join(' ') + const text = + Object.entries(ENTITY_TYPE) + .find(([, value]) => value === entityType)?.[0] + ?.toLowerCase() + ?.split('_') + ?.join(' ') || '' + // Return sentence case (capitalize first letter only) + return text.charAt(0).toUpperCase() + text.slice(1) } const exportTableAsCSV = async () => { diff --git a/apps/studio/components/ui/EntityTypeIcon.tsx b/apps/studio/components/ui/EntityTypeIcon.tsx index 4538f1ffdb38e..9114972669e0a 100644 --- a/apps/studio/components/ui/EntityTypeIcon.tsx +++ b/apps/studio/components/ui/EntityTypeIcon.tsx @@ -67,7 +67,8 @@ export const EntityTypeIcon = ({