Skip to content

Commit 6b80528

Browse files
authored
chore(studio): remove feature flag for dataApiExposedBadge (supabase#42563)
Cleanup / chore — removing a feature flag that has been at 100% rollout with no issues. ## What is the current behavior? The `dataApiExposedBadge` feature flag is checked at runtime via ConfigCat, even though it has been set to 100% for a while with no issues. ## What is the new behavior? The feature flag check is removed and the gated behavior is now unconditionally enabled. A reminder has been set to delete the flag from ConfigCat in a month. ## Summary by CodeRabbit **Refactor** * Simplified API access status indicators in the studio editor, ensuring security-related tooltips now display consistently based on actual access conditions. * Updated component interfaces and consolidated internal hook dependencies for improved code maintainability and organization.
1 parent c39747f commit 6b80528

File tree

3 files changed

+40
-40
lines changed

3 files changed

+40
-40
lines changed

apps/studio/components/layouts/TableEditorLayout/EntityListItem.tsx

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,13 @@
1-
import { useFlag, useParams } from 'common'
2-
import { buildTableEditorUrl } from 'components/grid/SupabaseGrid.utils'
3-
import { useTableFilter } from 'components/grid/hooks/useTableFilter'
4-
import { getEntityLintDetails } from 'components/interfaces/TableGridEditor/TableEntity.utils'
5-
import { EntityTypeIcon } from 'components/ui/EntityTypeIcon'
6-
import { InlineLink } from 'components/ui/InlineLink'
7-
import { getTableDefinition } from 'data/database/table-definition-query'
8-
import { ENTITY_TYPE } from 'data/entity-types/entity-type-constants'
9-
import { Entity } from 'data/entity-types/entity-types-infinite-query'
10-
import { useProjectLintsQuery } from 'data/lint/lint-query'
11-
import { EditorTablePageLink } from 'data/prefetchers/project.$ref.editor.$id'
12-
import type { TableApiAccessData, TableApiAccessMap } from 'data/privileges/table-api-access-query'
13-
import { useTableRowsCountQuery } from 'data/table-rows/table-rows-count-query'
14-
import { useQuerySchemaState } from 'hooks/misc/useSchemaQueryState'
15-
import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject'
1+
import { useParams } from 'common'
162
import { Copy, Download, Edit, Globe, Lock, MoreVertical, Trash } from 'lucide-react'
173
import Link from 'next/link'
184
import { type CSSProperties } from 'react'
195
import { toast } from 'sonner'
20-
import {
21-
type RoleImpersonationState,
22-
useRoleImpersonationStateSnapshot,
23-
} from 'state/role-impersonation-state'
24-
import { useTableEditorStateSnapshot } from 'state/table-editor'
25-
import { createTabId, useTabsStateSnapshot } from 'state/tabs'
266
import {
277
Badge,
288
Button,
9+
cn,
10+
copyToClipboard,
2911
DropdownMenu,
3012
DropdownMenuContent,
3113
DropdownMenuItem,
@@ -38,12 +20,33 @@ import {
3820
TooltipContent,
3921
TooltipTrigger,
4022
TreeViewItemVariant,
41-
cn,
42-
copyToClipboard,
4323
} from 'ui'
4424

4525
import { useExportAllRowsAsCsv, useExportAllRowsAsSql } from './ExportAllRows'
26+
import { useTableFilter } from '@/components/grid/hooks/useTableFilter'
27+
import { buildTableEditorUrl } from '@/components/grid/SupabaseGrid.utils'
28+
import { getEntityLintDetails } from '@/components/interfaces/TableGridEditor/TableEntity.utils'
29+
import { EntityTypeIcon } from '@/components/ui/EntityTypeIcon'
30+
import { InlineLink } from '@/components/ui/InlineLink'
31+
import { getTableDefinition } from '@/data/database/table-definition-query'
32+
import { ENTITY_TYPE } from '@/data/entity-types/entity-type-constants'
33+
import { Entity } from '@/data/entity-types/entity-types-infinite-query'
34+
import { useProjectLintsQuery } from '@/data/lint/lint-query'
35+
import { EditorTablePageLink } from '@/data/prefetchers/project.$ref.editor.$id'
36+
import type {
37+
TableApiAccessData,
38+
TableApiAccessMap,
39+
} from '@/data/privileges/table-api-access-query'
40+
import { useTableRowsCountQuery } from '@/data/table-rows/table-rows-count-query'
41+
import { useQuerySchemaState } from '@/hooks/misc/useSchemaQueryState'
42+
import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
4643
import { formatSql } from '@/lib/formatSql'
44+
import {
45+
useRoleImpersonationStateSnapshot,
46+
type RoleImpersonationState,
47+
} from '@/state/role-impersonation-state'
48+
import { useTableEditorStateSnapshot } from '@/state/table-editor'
49+
import { createTabId, useTabsStateSnapshot } from '@/state/tabs'
4750

4851
export interface EntityListItemProps {
4952
id: number | string
@@ -79,7 +82,6 @@ export const EntityListItem = ({
7982
const tabs = useTabsStateSnapshot()
8083
const isPreview = tabs.previewTabId === tabId
8184

82-
const isOpened = Object.values(tabs.tabsMap).some((tab) => tab.metadata?.tableId === entity.id)
8385
const isActive = Number(id) === entity.id
8486
const canEdit = isActive && !isLocked
8587

@@ -405,7 +407,6 @@ const EntityTooltipTrigger = ({
405407
apiAccessData?: TableApiAccessData
406408
}) => {
407409
const { ref } = useParams()
408-
const isDataApiExposedBadgeEnabled = useFlag('dataApiExposedBadge')
409410

410411
let tooltipContent = null
411412
const accessWarning = 'Data is publicly accessible via API'
@@ -476,7 +477,7 @@ const EntityTooltipTrigger = ({
476477
entity.type === ENTITY_TYPE.TABLE &&
477478
apiAccessData?.apiAccessType === 'access' &&
478479
tableHasRlsEnabledNoPolicyLint
479-
if (isDataApiExposedBadgeEnabled && isRlsEnabledNoPolicies) {
480+
if (isRlsEnabledNoPolicies) {
480481
return (
481482
<Tooltip>
482483
<TooltipTrigger className="min-w-4" aria-label="Table exposed via Data API">
@@ -492,7 +493,7 @@ const EntityTooltipTrigger = ({
492493

493494
const isApiExposedWithRlsAndPolicies =
494495
apiAccessData?.apiAccessType === 'access' && !tableHasRlsEnabledNoPolicyLint
495-
if (isDataApiExposedBadgeEnabled && isApiExposedWithRlsAndPolicies) {
496+
if (isApiExposedWithRlsAndPolicies) {
496497
return (
497498
<Tooltip>
498499
<TooltipTrigger className="min-w-4" aria-label="Table exposed via Data API">
Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
import { useFlag } from 'common'
2-
import { IS_TEST_ENV } from 'lib/constants'
31
import { usePHFlag } from '../ui/useFlag'
2+
import { IS_TEST_ENV } from '@/lib/constants'
43

54
/**
65
* Determine whether a user has access to Data API grant toggles.
@@ -12,13 +11,12 @@ import { usePHFlag } from '../ui/useFlag'
1211
* without requiring the feature flag infrastructure.
1312
*/
1413
export const useDataApiGrantTogglesEnabled = (): boolean => {
15-
const isDataApiBadgesEnabled = useFlag('dataApiExposedBadge')
1614
const isTableEditorApiAccessEnabled = usePHFlag<boolean>('tableEditorApiAccessToggle')
1715

1816
// In test environment, enable the feature for E2E testing
1917
if (IS_TEST_ENV) {
2018
return true
2119
}
2220

23-
return isDataApiBadgesEnabled && !!isTableEditorApiAccessEnabled
21+
return !!isTableEditorApiAccessEnabled
2422
}

e2e/studio/features/table-editor.spec.ts

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
import { expect, Page } from '@playwright/test'
21
import fs from 'fs'
32
import path from 'path'
4-
import { createTable as dbCreateTable, dropTable } from '../utils/db/index.js'
3+
import { expect, Page } from '@playwright/test'
4+
55
import { env } from '../env.config.js'
6+
import { createTable as dbCreateTable, dropTable } from '../utils/db/index.js'
67
import { releaseFileOnceCleanup, withFileOnceSetup } from '../utils/once-per-file.js'
78
import { resetLocalStorage } from '../utils/reset-local-storage.js'
89
import { test } from '../utils/test.js'
@@ -165,7 +166,7 @@ testRunner('table editor', () => {
165166
await page
166167
.getByRole('button', { name: `View ${tableNameActions}`, exact: true })
167168
.getByRole('button')
168-
.nth(1)
169+
.nth(2)
169170
.click()
170171
await page.getByRole('menuitem', { name: 'Copy name' }).click()
171172
await page.waitForTimeout(500)
@@ -176,7 +177,7 @@ testRunner('table editor', () => {
176177
await page
177178
.getByRole('button', { name: `View ${tableNameActions}`, exact: true })
178179
.getByRole('button')
179-
.nth(1)
180+
.nth(2)
180181
.click()
181182
await page.getByRole('menuitem', { name: 'Copy table schema' }).click()
182183
await waitForApiResponse(page, 'pg-meta', ref, 'query?key=table-definition-') // wait for endpoint to generate schema
@@ -193,7 +194,7 @@ testRunner('table editor', () => {
193194
await page
194195
.getByRole('button', { name: `View ${tableNameActions}`, exact: true })
195196
.getByRole('button')
196-
.nth(1)
197+
.nth(2)
197198
.click()
198199
await page.getByRole('menuitem', { name: 'Duplicate table' }).click()
199200
await page.getByRole('button', { name: 'Save' }).click()
@@ -367,7 +368,7 @@ testRunner('table editor', () => {
367368
await page
368369
.getByRole('button', { name: `View ${tableNameGridEditor}`, exact: true })
369370
.getByRole('button')
370-
.nth(1)
371+
.nth(2)
371372
.click()
372373
await page.getByRole('menuitem', { name: 'Edit table' }).click()
373374
await page.getByTestId('table-name-input').fill(tableNameUpdated)
@@ -386,7 +387,7 @@ testRunner('table editor', () => {
386387
await page
387388
.getByRole('button', { name: `View ${tableNameUpdated}`, exact: true })
388389
.getByRole('button')
389-
.nth(1)
390+
.nth(2)
390391
.click()
391392
// Open nested export submenu via keyboard (more stable than hover in headless)
392393
const exportDataItemCsv = page.getByRole('menuitem', { name: 'Export data' })
@@ -425,7 +426,7 @@ testRunner('table editor', () => {
425426
await page
426427
.getByRole('button', { name: `View ${tableNameUpdated}`, exact: true })
427428
.getByRole('button')
428-
.nth(1)
429+
.nth(2)
429430
.click()
430431
// Open nested export submenu via keyboard (more stable than hover in headless)
431432
const exportDataItemSql = page.getByRole('menuitem', { name: 'Export data' })
@@ -459,7 +460,7 @@ testRunner('table editor', () => {
459460
await page
460461
.getByRole('button', { name: `View ${tableNameUpdated}`, exact: true })
461462
.getByRole('button')
462-
.nth(1)
463+
.nth(2)
463464
.click()
464465

465466
const exportDataItemCli = page.getByRole('menuitem', { name: 'Export data' })

0 commit comments

Comments
 (0)