diff --git a/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreview.constants.tsx b/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreview.constants.tsx index ceadbd396bf19..c2b2c54f742e2 100644 --- a/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreview.constants.tsx +++ b/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreview.constants.tsx @@ -8,20 +8,6 @@ export const FEATURE_PREVIEWS = [ isNew: true, isPlatformOnly: false, }, - { - key: LOCAL_STORAGE_KEYS.UI_TABLE_EDITOR_TABS, - name: 'Table Editor Tabs', - discussionsUrl: 'https://github.com/orgs/supabase/discussions/35636', - isNew: true, - isPlatformOnly: false, - }, - { - key: LOCAL_STORAGE_KEYS.UI_SQL_EDITOR_TABS, - name: 'SQL Editor Tabs', - discussionsUrl: 'https://github.com/orgs/supabase/discussions/35636', - isNew: true, - isPlatformOnly: true, - }, { key: LOCAL_STORAGE_KEYS.UI_PREVIEW_API_SIDE_PANEL, name: 'Project API documentation', diff --git a/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreviewContext.tsx b/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreviewContext.tsx index 4fa0a7dcf672b..bef4199d7ccf7 100644 --- a/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreviewContext.tsx +++ b/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreviewContext.tsx @@ -2,8 +2,6 @@ import { noop } from 'lodash' import { PropsWithChildren, createContext, useContext, useEffect, useState } from 'react' import { FeatureFlagContext, LOCAL_STORAGE_KEYS } from 'common' -import { useFlag } from 'hooks/ui/useFlag' -import { IS_PLATFORM } from 'lib/constants' import { EMPTY_OBJ } from 'lib/void' import { FEATURE_PREVIEWS } from './FeaturePreview.constants' @@ -21,15 +19,10 @@ export const useFeaturePreviewContext = () => useContext(FeaturePreviewContext) export const FeaturePreviewContextProvider = ({ children }: PropsWithChildren<{}>) => { const { hasLoaded } = useContext(FeatureFlagContext) - const enableTabsInterface = useFlag('tabsInterface') // [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_SQL_EDITOR_TABS: - return enableTabsInterface - case LOCAL_STORAGE_KEYS.UI_TABLE_EDITOR_TABS: - return enableTabsInterface default: return false } @@ -86,14 +79,3 @@ export const useIsInlineEditorEnabled = () => { const { flags } = useFeaturePreviewContext() return flags[LOCAL_STORAGE_KEYS.UI_PREVIEW_INLINE_EDITOR] } - -export const useIsTableEditorTabsEnabled = () => { - const { flags } = useFeaturePreviewContext() - return flags[LOCAL_STORAGE_KEYS.UI_TABLE_EDITOR_TABS] -} - -export const useIsSQLEditorTabsEnabled = () => { - const { flags } = useFeaturePreviewContext() - if (!IS_PLATFORM) return false - return flags[LOCAL_STORAGE_KEYS.UI_SQL_EDITOR_TABS] -} diff --git a/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreviewModal.tsx b/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreviewModal.tsx index 94bc324361f10..f7a047d003b89 100644 --- a/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreviewModal.tsx +++ b/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreviewModal.tsx @@ -14,15 +14,11 @@ import { CLSPreview } from './CLSPreview' import { FEATURE_PREVIEWS } from './FeaturePreview.constants' import { useFeaturePreviewContext } from './FeaturePreviewContext' import { InlineEditorPreview } from './InlineEditorPreview' -import { SqlEditorTabsPreview } from './SqlEditorTabs' -import { TableEditorTabsPreview } from './TableEditorTabs' const FEATURE_PREVIEW_KEY_TO_CONTENT: { [key: string]: ReactNode } = { [LOCAL_STORAGE_KEYS.UI_PREVIEW_INLINE_EDITOR]: , - [LOCAL_STORAGE_KEYS.UI_TABLE_EDITOR_TABS]: , - [LOCAL_STORAGE_KEYS.UI_SQL_EDITOR_TABS]: , [LOCAL_STORAGE_KEYS.UI_PREVIEW_API_SIDE_PANEL]: , [LOCAL_STORAGE_KEYS.UI_PREVIEW_CLS]: , } diff --git a/apps/studio/components/interfaces/App/FeaturePreview/InlineEditorPreview.tsx b/apps/studio/components/interfaces/App/FeaturePreview/InlineEditorPreview.tsx index 08a82c3f74c87..228da9d8b4d00 100644 --- a/apps/studio/components/interfaces/App/FeaturePreview/InlineEditorPreview.tsx +++ b/apps/studio/components/interfaces/App/FeaturePreview/InlineEditorPreview.tsx @@ -1,7 +1,6 @@ import Image from 'next/image' import { BASE_PATH } from 'lib/constants' -import { Admonition } from 'ui-patterns' export const InlineEditorPreview = () => { return ( diff --git a/apps/studio/components/interfaces/App/FeaturePreview/SqlEditorTabs.tsx b/apps/studio/components/interfaces/App/FeaturePreview/SqlEditorTabs.tsx deleted file mode 100644 index ee053af865739..0000000000000 --- a/apps/studio/components/interfaces/App/FeaturePreview/SqlEditorTabs.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import { BASE_PATH } from 'lib/constants' -import Image from 'next/image' - -export const SqlEditorTabsPreview = () => { - return ( -
- api-docs-side-panel-preview -

- The SQL Editor now features tabs for improved navigation and organization. Conveniently go - between the queries that you're focused on, and collapse the sidebar for a bigger real - estate while writing your queries. -

-
-

Enabling this preview will:

-
    -
  • Enable opening of queries in the SQL Editor as tabs
  • -
  • Support closing of the navigation sidebar for a larger code editor space
  • -
-
-
- ) -} diff --git a/apps/studio/components/interfaces/App/FeaturePreview/TableEditorTabs.tsx b/apps/studio/components/interfaces/App/FeaturePreview/TableEditorTabs.tsx deleted file mode 100644 index 1a83d1e70dd29..0000000000000 --- a/apps/studio/components/interfaces/App/FeaturePreview/TableEditorTabs.tsx +++ /dev/null @@ -1,192 +0,0 @@ -import { ExternalLink, X } from 'lucide-react' -import Image from 'next/image' - -import { LOCAL_STORAGE_KEYS } from 'common' -import { useEditorType } from 'components/layouts/editors/EditorsLayout.hooks' -import { ButtonTooltip } from 'components/ui/ButtonTooltip' -import { InlineLinkClassName } from 'components/ui/InlineLink' -import { useLocalStorageQuery } from 'hooks/misc/useLocalStorage' -import { BASE_PATH } from 'lib/constants' -import { useAppStateSnapshot } from 'state/app-state' -import { - Alert_Shadcn_, - AlertDescription_Shadcn_, - AlertTitle_Shadcn_, - Badge, - Button, - cn, - HoverCard, - HoverCardContent_Shadcn_, - HoverCardTrigger_Shadcn_, -} from 'ui' -import { useIsSQLEditorTabsEnabled, useIsTableEditorTabsEnabled } from './FeaturePreviewContext' - -export const TableEditorTabsPreview = () => { - return ( -
- api-docs-side-panel-preview -

- The Table Editor now features tabs for improved navigation and organization. Have multiple - tables opened across schemas and conveniently go across them without having to switch - schemas. Collapse the sidebar for a bigger real estate while browsing your data. -

-
-

Enabling this preview will:

-
    -
  • Enable opening of tables in the Table Editor as tabs
  • -
  • Support closing of the navigation sidebar for a larger data grid space
  • -
-
-
- ) -} - -export const TabsUpdateCallout = () => { - const editor = useEditorType() - const appSnap = useAppStateSnapshot() - - const isTableEditorTabsEnabled = useIsTableEditorTabsEnabled() - const isSQLEditorTabsEnabled = useIsSQLEditorTabsEnabled() - const isTabsEnabled = isTableEditorTabsEnabled || isSQLEditorTabsEnabled - - const [tableEditorTabsPreviewState] = useLocalStorageQuery( - LOCAL_STORAGE_KEYS.UI_TABLE_EDITOR_TABS, - '' - ) - const [sqlEditorTabsPreviewState] = useLocalStorageQuery( - LOCAL_STORAGE_KEYS.UI_SQL_EDITOR_TABS, - '' - ) - - const [tabsInterfaceAcknowledge, setTabsInterfaceAcknowledge] = useLocalStorageQuery( - LOCAL_STORAGE_KEYS.TABS_INTERFACE_ACKNOWLEDGED, - false - ) - const isDefaultOptedInTabs = - isTabsEnabled && tableEditorTabsPreviewState === '' && sqlEditorTabsPreviewState === '' - - if (!isDefaultOptedInTabs || tabsInterfaceAcknowledge) return null - - return ( - - - - NEW - - Tabs Interface for Editors - - - The Table and SQL Editors now feature tabs for improved navigation and organization! Check - out our{' '} - { - appSnap.setSelectedFeaturePreview( - editor === 'table' - ? LOCAL_STORAGE_KEYS.UI_TABLE_EDITOR_TABS - : LOCAL_STORAGE_KEYS.UI_SQL_EDITOR_TABS - ) - appSnap.setShowFeaturePreviewModal(true) - }} - > - feature previews - {' '} - for more information. - - - - - } - className="absolute top-2 right-2 px-1" - onClick={() => setTabsInterfaceAcknowledge(true)} - tooltip={{ content: { side: 'bottom', text: 'Dismiss' } }} - /> - - ) -} - -export const TabsUpdateTooltip = () => { - const editor = useEditorType() - const appSnap = useAppStateSnapshot() - - const isTableEditorTabsEnabled = useIsTableEditorTabsEnabled() - const isSQLEditorTabsEnabled = useIsSQLEditorTabsEnabled() - const isTabsEnabled = isTableEditorTabsEnabled || isSQLEditorTabsEnabled - - const [tableEditorTabsPreviewState] = useLocalStorageQuery( - LOCAL_STORAGE_KEYS.UI_TABLE_EDITOR_TABS, - '' - ) - const [sqlEditorTabsPreviewState] = useLocalStorageQuery( - LOCAL_STORAGE_KEYS.UI_SQL_EDITOR_TABS, - '' - ) - const [tabsInterfaceAcknowledge, setTabsInterfaceAcknowledge] = useLocalStorageQuery( - LOCAL_STORAGE_KEYS.TABS_INTERFACE_ACKNOWLEDGED, - false - ) - - const isDefaultOptedInTabs = - isTabsEnabled && tableEditorTabsPreviewState === '' && sqlEditorTabsPreviewState === '' - - if (!isDefaultOptedInTabs || tabsInterfaceAcknowledge) return null - - return ( - - -
- - NEW - -
-
- -
-

Tabs Interface for Editors

-

- The Table and SQL Editors now feature tabs for improved navigation and organization! - Check out our{' '} - { - appSnap.setSelectedFeaturePreview( - editor === 'table' - ? LOCAL_STORAGE_KEYS.UI_TABLE_EDITOR_TABS - : LOCAL_STORAGE_KEYS.UI_SQL_EDITOR_TABS - ) - appSnap.setShowFeaturePreviewModal(true) - }} - > - feature previews - {' '} - for more information. -

-
- -
-
- ) -} diff --git a/apps/studio/components/interfaces/Functions/EdgeFunctionSecrets/EdgeFunctionSecrets.tsx b/apps/studio/components/interfaces/Functions/EdgeFunctionSecrets/EdgeFunctionSecrets.tsx index 98c2e51e0651b..4aba64bac4e89 100644 --- a/apps/studio/components/interfaces/Functions/EdgeFunctionSecrets/EdgeFunctionSecrets.tsx +++ b/apps/studio/components/interfaces/Functions/EdgeFunctionSecrets/EdgeFunctionSecrets.tsx @@ -42,6 +42,18 @@ const EdgeFunctionSecrets = () => { [] : data ?? [] + const headers = [ + Name, + + Digest{' '} + + SHA256 + + , + Updated at, + , + ] + return ( <> {isLoading && } @@ -73,17 +85,7 @@ const EdgeFunctionSecrets = () => {
Name, - - Digest{' '} - - SHA256 - - , - Updated at, - , - ]} + head={headers} body={ secrets.length > 0 ? ( secrets.map((secret) => ( @@ -95,7 +97,7 @@ const EdgeFunctionSecrets = () => { )) ) : secrets.length === 0 && searchString.length > 0 ? ( - +

No results found

Your search for "{searchString}" did not return any results @@ -104,7 +106,7 @@ const EdgeFunctionSecrets = () => { ) : ( - +

No secrets created

There are no secrets associated with your project yet diff --git a/apps/studio/components/interfaces/SQLEditor/RenameQueryModal.tsx b/apps/studio/components/interfaces/SQLEditor/RenameQueryModal.tsx index 2f062081911e5..35af13d854351 100644 --- a/apps/studio/components/interfaces/SQLEditor/RenameQueryModal.tsx +++ b/apps/studio/components/interfaces/SQLEditor/RenameQueryModal.tsx @@ -3,6 +3,7 @@ import { toast } from 'sonner' import { useParams } from 'common' import { useSqlTitleGenerateMutation } from 'data/ai/sql-title-mutation' +import { useProjectSettingsV2Query } from 'data/config/project-settings-v2-query' import { getContentById } from 'data/content/content-id-query' import { UpsertContentPayload, @@ -11,12 +12,10 @@ import { import { Snippet } from 'data/content/sql-folders-query' import type { SqlSnippet } from 'data/content/sql-snippets-query' import { useOrgSubscriptionQuery } from 'data/subscriptions/org-subscription-query' -import { useProjectSettingsV2Query } from 'data/config/project-settings-v2-query' import { useSelectedOrganization } from 'hooks/misc/useSelectedOrganization' import { useSqlEditorV2StateSnapshot } from 'state/sql-editor-v2' import { createTabId, useTabsStateSnapshot } from 'state/tabs' import { AiIconAnimation, Button, Form, Input, Modal } from 'ui' -import { useIsSQLEditorTabsEnabled } from '../App/FeaturePreview/FeaturePreviewContext' import { subscriptionHasHipaaAddon } from '../Billing/Subscription/Subscription.utils' export interface RenameQueryModalProps { @@ -42,7 +41,6 @@ const RenameQueryModal = ({ { enabled: visible } ) const isSQLSnippet = snippet.type === 'sql' - const isSQLEditorTabsEnabled = useIsSQLEditorTabsEnabled() const { data: projectSettings } = useProjectSettingsV2Query({ projectRef: ref }) // Customers on HIPAA plans should not have access to Supabase AI @@ -112,10 +110,8 @@ const RenameQueryModal = ({ snapV2.renameSnippet({ id, name: nameInput, description: descriptionInput }) - if (isSQLEditorTabsEnabled && ref) { - const tabId = createTabId('sql', { id }) - tabsSnap.updateTab(tabId, { label: nameInput }) - } + const tabId = createTabId('sql', { id }) + tabsSnap.updateTab(tabId, { label: nameInput }) toast.success('Successfully renamed snippet!') if (onComplete) onComplete() diff --git a/apps/studio/components/interfaces/SQLEditor/SQLEditor.tsx b/apps/studio/components/interfaces/SQLEditor/SQLEditor.tsx index 054174f05f34d..fb4e091477247 100644 --- a/apps/studio/components/interfaces/SQLEditor/SQLEditor.tsx +++ b/apps/studio/components/interfaces/SQLEditor/SQLEditor.tsx @@ -51,7 +51,6 @@ import { TooltipTrigger, cn, } from 'ui' -import { useIsSQLEditorTabsEnabled } from '../App/FeaturePreview/FeaturePreviewContext' import { useSqlEditorDiff, useSqlEditorPrompt } from './hooks' import { RunQueryWarningModal } from './RunQueryWarningModal' import { @@ -95,7 +94,6 @@ export const SQLEditor = () => { const { isOptedInToAI, isHipaaProjectDisallowed } = useOrgOptedIntoAiAndHippaProject() const [selectedSchemas] = useSchemasForAi(project?.ref!) const includeSchemaMetadata = (isOptedInToAI && !isHipaaProjectDisallowed) || !IS_PLATFORM - const isSQLEditorTabsEnabled = useIsSQLEditorTabsEnabled() const { sourceSqlDiff, @@ -212,10 +210,8 @@ export const SQLEditor = () => { try { const { title: name } = await generateSqlTitle({ sql }) snapV2.renameSnippet({ id, name }) - if (isSQLEditorTabsEnabled && ref) { - const tabId = createTabId('sql', { id }) - tabs.updateTab(tabId, { label: name }) - } + const tabId = createTabId('sql', { id }) + tabs.updateTab(tabId, { label: name }) } catch (error) { // [Joshen] No error handler required as this happens in the background and not necessary to ping the user } diff --git a/apps/studio/components/interfaces/Sidebar.tsx b/apps/studio/components/interfaces/Sidebar.tsx index 11ef4f28fa6eb..bb7625b410a7f 100644 --- a/apps/studio/components/interfaces/Sidebar.tsx +++ b/apps/studio/components/interfaces/Sidebar.tsx @@ -42,10 +42,7 @@ import { Sidebar as SidebarPrimitive, useSidebar, } from 'ui' -import { - useIsAPIDocsSidePanelEnabled, - useIsSQLEditorTabsEnabled, -} from './App/FeaturePreview/FeaturePreviewContext' +import { useIsAPIDocsSidePanelEnabled } from './App/FeaturePreview/FeaturePreviewContext' export const ICON_SIZE = 32 export const ICON_STROKE_WIDTH = 1.5 @@ -228,7 +225,6 @@ const ProjectLinks = () => { const showWarehouse = useFlag('warehouse') const showUnifiedLogs = useFlag('unifiedLogs') - const isSqlEditorTabsEnabled = useIsSQLEditorTabsEnabled() const activeRoute = router.pathname.split('/')[3] @@ -244,9 +240,7 @@ const ProjectLinks = () => { 'realtime:all', ]) - const toolRoutes = generateToolRoutes(ref, project, { - sqlEditorTabs: isSqlEditorTabsEnabled, - }) + const toolRoutes = generateToolRoutes(ref, project) const productRoutes = generateProductRoutes(ref, project, { auth: authEnabled, edgeFunctions: edgeFunctionsEnabled, diff --git a/apps/studio/components/interfaces/TableGridEditor/EmptyState.tsx b/apps/studio/components/interfaces/TableGridEditor/EmptyState.tsx deleted file mode 100644 index 0fbf052477c17..0000000000000 --- a/apps/studio/components/interfaces/TableGridEditor/EmptyState.tsx +++ /dev/null @@ -1,66 +0,0 @@ -import { PermissionAction } from '@supabase/shared-types/out/constants' - -import { useProjectContext } from 'components/layouts/ProjectLayout/ProjectContext' -import ProductEmptyState from 'components/to-be-cleaned/ProductEmptyState' -import { useEntityTypesQuery } from 'data/entity-types/entity-types-infinite-query' -import { useCheckPermissions } from 'hooks/misc/useCheckPermissions' -import { useLocalStorage } from 'hooks/misc/useLocalStorage' -import { useQuerySchemaState } from 'hooks/misc/useSchemaQueryState' -import { PROTECTED_SCHEMAS } from 'lib/constants/schemas' -import { useTableEditorStateSnapshot } from 'state/table-editor' - -export interface EmptyStateProps {} - -const EmptyState = ({}: EmptyStateProps) => { - const snap = useTableEditorStateSnapshot() - const { selectedSchema } = useQuerySchemaState() - const isProtectedSchema = PROTECTED_SCHEMAS.includes(selectedSchema) - const canCreateTables = - useCheckPermissions(PermissionAction.TENANT_SQL_ADMIN_WRITE, 'tables') && !isProtectedSchema - - const [sort] = useLocalStorage<'alphabetical' | 'grouped-alphabetical'>( - 'table-editor-sort', - 'alphabetical' - ) - - const { project } = useProjectContext() - const { data } = useEntityTypesQuery({ - projectRef: project?.ref, - connectionString: project?.connectionString, - schemas: [selectedSchema], - sort, - }) - - const totalCount = data?.pages?.[0].data.count ?? 0 - - return ( -

- {totalCount === 0 ? ( - -

- There are no tables available in this schema. -

-
- ) : ( -
- -

- Select a table from the navigation panel on the left to view its data - {canCreateTables && ', or create a new one.'} -

-
-
- )} -
- ) -} - -export default EmptyState diff --git a/apps/studio/components/interfaces/TableGridEditor/SidePanelEditor/SidePanelEditor.tsx b/apps/studio/components/interfaces/TableGridEditor/SidePanelEditor/SidePanelEditor.tsx index 2bfb205ed15b4..debbd89ef68ff 100644 --- a/apps/studio/components/interfaces/TableGridEditor/SidePanelEditor/SidePanelEditor.tsx +++ b/apps/studio/components/interfaces/TableGridEditor/SidePanelEditor/SidePanelEditor.tsx @@ -5,7 +5,6 @@ import { useState } from 'react' import { toast } from 'sonner' import { useParams } from 'common' -import { useIsTableEditorTabsEnabled } from 'components/interfaces/App/FeaturePreview/FeaturePreviewContext' import { useProjectContext } from 'components/layouts/ProjectLayout/ProjectContext' import { useDatabasePublicationCreateMutation } from 'data/database-publications/database-publications-create-mutation' import { useDatabasePublicationsQuery } from 'data/database-publications/database-publications-query' @@ -21,6 +20,7 @@ import { tableRowKeys } from 'data/table-rows/keys' import { useTableRowCreateMutation } from 'data/table-rows/table-row-create-mutation' import { useTableRowUpdateMutation } from 'data/table-rows/table-row-update-mutation' import { tableKeys } from 'data/tables/keys' +import { RetrieveTableResult } from 'data/tables/table-retrieve-query' import { getTables } from 'data/tables/tables-query' import { useUrlState } from 'hooks/ui/useUrlState' import { useGetImpersonatedRoleState } from 'state/role-impersonation-state' @@ -50,7 +50,6 @@ import { import SpreadsheetImport from './SpreadsheetImport/SpreadsheetImport' import TableEditor from './TableEditor/TableEditor' import type { ImportContent } from './TableEditor/TableEditor.types' -import { RetrieveTableResult } from 'data/tables/table-retrieve-query' export interface SidePanelEditorProps { editable?: boolean @@ -71,7 +70,6 @@ const SidePanelEditor = ({ const { ref } = useParams() const snap = useTableEditorStateSnapshot() const tabsSnap = useTabsStateSnapshot() - const isTableEditorTabsEnabled = useIsTableEditorTabsEnabled() const [_, setParams] = useUrlState({ arrayKeys: ['filter', 'sort'] }) const queryClient = useQueryClient() @@ -493,7 +491,7 @@ const SidePanelEditor = ({ `Table ${table.name} has been updated but there were some errors. Please check these errors separately.` ) } else { - if (isTableEditorTabsEnabled && ref && payload.name) { + if (ref && payload.name) { // [Joshen] Only table entities can be updated via the dashboard const tabId = createTabId(ENTITY_TYPE.TABLE, { id: selectedTable.id }) tabsSnap.updateTab(tabId, { label: payload.name }) diff --git a/apps/studio/components/interfaces/TableGridEditor/TableGridEditor.tsx b/apps/studio/components/interfaces/TableGridEditor/TableGridEditor.tsx index 08ec744a22f06..a29a158fc05a3 100644 --- a/apps/studio/components/interfaces/TableGridEditor/TableGridEditor.tsx +++ b/apps/studio/components/interfaces/TableGridEditor/TableGridEditor.tsx @@ -1,5 +1,5 @@ import { PermissionAction } from '@supabase/shared-types/out/constants' -import { isUndefined } from 'lodash' +import Link from 'next/link' import { useRouter } from 'next/router' import { useCallback } from 'react' @@ -18,13 +18,11 @@ import { useQuerySchemaState } from 'hooks/misc/useSchemaQueryState' import { useSelectedProject } from 'hooks/misc/useSelectedProject' import { useUrlState } from 'hooks/ui/useUrlState' import { PROTECTED_SCHEMAS } from 'lib/constants/schemas' -import Link from 'next/link' import { useAppStateSnapshot } from 'state/app-state' import { TableEditorTableStateContextProvider } from 'state/table-editor-table' import { createTabId, useTabsStateSnapshot } from 'state/tabs' import { Button } from 'ui' import { Admonition, GenericSkeletonLoader } from 'ui-patterns' -import { useIsTableEditorTabsEnabled } from '../App/FeaturePreview/FeaturePreviewContext' import DeleteConfirmationDialogs from './DeleteConfirmationDialogs' import SidePanelEditor from './SidePanelEditor/SidePanelEditor' import TableDefinition from './TableDefinition' @@ -44,7 +42,6 @@ export const TableGridEditor = ({ const { ref: projectRef, id } = useParams() const tabs = useTabsStateSnapshot() - const isTableEditorTabsEnabled = useIsTableEditorTabsEnabled() const { selectedSchema } = useQuerySchemaState() useLoadTableEditorStateFromLocalStorageIntoUrl({ @@ -65,9 +62,9 @@ export const TableGridEditor = ({ connectionString: project?.connectionString, }) - const onClearDashboardHistory = () => { + const onClearDashboardHistory = useCallback(() => { if (projectRef) appSnap.setDashboardHistory(projectRef, 'editor', undefined) - } + }, [appSnap, projectRef]) const onTableCreated = useCallback( (table: { id: number }) => { @@ -78,19 +75,12 @@ export const TableGridEditor = ({ const onTableDeleted = useCallback(async () => { // For simplicity for now, we just open the first table within the same schema - if (isTableEditorTabsEnabled && selectedTable) { + if (selectedTable) { // Close tab const tabId = createTabId(selectedTable.entity_type, { id: selectedTable.id }) tabs.handleTabClose({ id: tabId, router, editor: 'table', onClearDashboardHistory }) - } else { - const tables = await getTables(selectedSchema) - if (tables.length > 0) { - router.push(`/project/${projectRef}/editor/${tables[0].id}`) - } else { - router.push(`/project/${projectRef}/editor`) - } } - }, [getTables, isTableEditorTabsEnabled, projectRef, router, selectedSchema]) + }, [onClearDashboardHistory, router, selectedTable, tabs]) // NOTE: DO NOT PUT HOOKS AFTER THIS LINE if (isLoadingSelectedTable || !projectRef) { @@ -105,7 +95,7 @@ export const TableGridEditor = ({ ) } - if (isUndefined(selectedTable)) { + if (!selectedTable) { return (
@@ -114,45 +104,41 @@ export const TableGridEditor = ({ title={`Unable to find your table with ID ${id}`} description="This table doesn't exist in your database" > - {isTableEditorTabsEnabled && ( - <> - {!!tabId ? ( - - ) : openTabs.length > 0 ? ( - - ) : ( - - )} - + {!!tabId ? ( + + ) : openTabs.length > 0 ? ( + + ) : ( + )}
diff --git a/apps/studio/components/interfaces/TableGridEditor/index.ts b/apps/studio/components/interfaces/TableGridEditor/index.ts index 50e1839b9862c..52936211e7e82 100644 --- a/apps/studio/components/interfaces/TableGridEditor/index.ts +++ b/apps/studio/components/interfaces/TableGridEditor/index.ts @@ -1,2 +1 @@ -export { default as EmptyState } from './EmptyState' export { default as SidePanelEditor } from './SidePanelEditor/SidePanelEditor' diff --git a/apps/studio/components/layouts/ProjectLayout/NavigationBar/NavigationBar.utils.tsx b/apps/studio/components/layouts/ProjectLayout/NavigationBar/NavigationBar.utils.tsx index ac33ba4ff1da4..41a6434e1977e 100644 --- a/apps/studio/components/layouts/ProjectLayout/NavigationBar/NavigationBar.utils.tsx +++ b/apps/studio/components/layouts/ProjectLayout/NavigationBar/NavigationBar.utils.tsx @@ -19,12 +19,7 @@ import { } from 'icons' import { IS_PLATFORM, PROJECT_STATUS } from 'lib/constants' -export const generateToolRoutes = ( - ref?: string, - project?: Project, - features?: { sqlEditorTabs: boolean } -): Route[] => { - const { sqlEditorTabs } = features ?? {} +export const generateToolRoutes = (ref?: string, project?: Project, features?: {}): Route[] => { const isProjectBuilding = project?.status === PROJECT_STATUS.COMING_UP const buildingUrl = `/project/${ref}` @@ -42,8 +37,7 @@ export const generateToolRoutes = ( icon: , link: !IS_PLATFORM ? `/project/${ref}/sql/1` - : ref && - (isProjectBuilding ? buildingUrl : `/project/${ref}/sql${!!sqlEditorTabs ? '' : '/new'}`), + : ref && (isProjectBuilding ? buildingUrl : `/project/${ref}/sql`), }, ] } diff --git a/apps/studio/components/layouts/ProjectLayout/ProjectLayout.tsx b/apps/studio/components/layouts/ProjectLayout/ProjectLayout.tsx index 3c887f9ac369e..0d6d6f1fcd957 100644 --- a/apps/studio/components/layouts/ProjectLayout/ProjectLayout.tsx +++ b/apps/studio/components/layouts/ProjectLayout/ProjectLayout.tsx @@ -4,10 +4,6 @@ import { useRouter } from 'next/router' import { forwardRef, Fragment, PropsWithChildren, ReactNode, useEffect, useState } from 'react' import { useParams } from 'common' -import { - useIsSQLEditorTabsEnabled, - useIsTableEditorTabsEnabled, -} from 'components/interfaces/App/FeaturePreview/FeaturePreviewContext' import ProjectAPIDocs from 'components/interfaces/ProjectAPIDocs/ProjectAPIDocs' import { AIAssistant } from 'components/ui/AIAssistantPanel/AIAssistant' import AISettingsModal from 'components/ui/AISettingsModal' @@ -101,14 +97,8 @@ const ProjectLayout = forwardRef { const snapV2 = useSqlEditorV2StateSnapshot() const tabs = useTabsStateSnapshot() - const isSQLEditorTabsEnabled = useIsSQLEditorTabsEnabled() const [sectionVisibility, setSectionVisibility] = useLocalStorage( LOCAL_STORAGE_KEYS.SQL_EDITOR_SECTION_STATE(projectRef ?? ''), @@ -293,12 +292,10 @@ export const SQLEditorNav = ({ sort = 'inserted_at' }: SQLEditorNavProps) => { const { mutate: deleteContent, isLoading: isDeleting } = useContentDeleteMutation({ onSuccess: (data) => { - if (isSQLEditorTabsEnabled) { - // Update Tabs state - currently unknown how to differentiate between sql and non-sql content - // so we're just deleting all tabs for with matching IDs - const tabIds = data.map((id) => createTabId('sql', { id })) - tabs.removeTabs(tabIds) - } + // Update Tabs state - currently unknown how to differentiate between sql and non-sql content + // so we're just deleting all tabs for with matching IDs + const tabIds = data.map((id) => createTabId('sql', { id })) + tabs.removeTabs(tabIds) }, onError: (error, data) => { if (error.message.includes('Contents not found')) { @@ -541,10 +538,10 @@ export const SQLEditorNav = ({ sort = 'inserted_at' }: SQLEditorNavProps) => { const sqlEditorTabsCleanup = useSqlEditorTabsCleanup() useEffect(() => { - if (isSuccess && isSQLEditorTabsEnabled) { + if (isSuccess) { sqlEditorTabsCleanup({ snippets: allSnippetsInView as any }) } - }, [allSnippetsInView, isSQLEditorTabsEnabled, isSuccess, sqlEditorTabsCleanup]) + }, [allSnippetsInView, isSuccess, sqlEditorTabsCleanup]) return ( <> @@ -572,15 +569,13 @@ export const SQLEditorNav = ({ sort = 'inserted_at' }: SQLEditorNavProps) => { data={projectSnippetsTreeState} aria-label="project-level-snippets" nodeRenderer={({ element, ...props }) => { - const isOpened = - isSQLEditorTabsEnabled && - Object.values(tabs.tabsMap).some( - (tab) => tab.metadata?.sqlId === element.metadata?.id - ) + const isOpened = Object.values(tabs.tabsMap).some( + (tab) => tab.metadata?.sqlId === element.metadata?.id + ) const tabId = createTabId('sql', { id: element?.metadata?.id as unknown as Snippet['id'], }) - const isPreview = isSQLEditorTabsEnabled && tabs.previewTabId === tabId + const isPreview = tabs.previewTabId === tabId const isActive = !isPreview && element.metadata?.id === id const isSelected = selectedSnippets.some((x) => x.id === element.metadata?.id) @@ -656,15 +651,13 @@ export const SQLEditorNav = ({ sort = 'inserted_at' }: SQLEditorNavProps) => { data={favoritesTreeState} aria-label="favorite-snippets" nodeRenderer={({ element, ...props }) => { - const isOpened = - isSQLEditorTabsEnabled && - Object.values(tabs.tabsMap).some( - (tab) => tab.metadata?.sqlId === element.metadata?.id - ) + const isOpened = Object.values(tabs.tabsMap).some( + (tab) => tab.metadata?.sqlId === element.metadata?.id + ) const tabId = createTabId('sql', { id: element?.metadata?.id as unknown as Snippet['id'], }) - const isPreview = isSQLEditorTabsEnabled && tabs.previewTabId === tabId + const isPreview = tabs.previewTabId === tabId const isActive = !isPreview && element.metadata?.id === id const isSelected = selectedSnippets.some((x) => x.id === element.metadata?.id) @@ -746,15 +739,13 @@ export const SQLEditorNav = ({ sort = 'inserted_at' }: SQLEditorNavProps) => { }} expandedIds={expandedFolderIds} nodeRenderer={({ element, ...props }) => { - const isOpened = - isSQLEditorTabsEnabled && - Object.values(tabs.tabsMap).some( - (tab) => tab.metadata?.sqlId === element.metadata?.id - ) + const isOpened = Object.values(tabs.tabsMap).some( + (tab) => tab.metadata?.sqlId === element.metadata?.id + ) const tabId = createTabId('sql', { id: element?.metadata?.id as unknown as Snippet['id'], }) - const isPreview = isSQLEditorTabsEnabled && tabs.previewTabId === tabId + const isPreview = tabs.previewTabId === tabId const isActive = !isPreview && element.metadata?.id === id const isSelected = selectedSnippets.some((x) => x.id === element.metadata?.id) diff --git a/apps/studio/components/layouts/SQLEditorLayout/SQLEditorNavV2/SQLEditorTreeViewItem.tsx b/apps/studio/components/layouts/SQLEditorLayout/SQLEditorNavV2/SQLEditorTreeViewItem.tsx index 895eaee2bb292..3633fdf5b74f5 100644 --- a/apps/studio/components/layouts/SQLEditorLayout/SQLEditorNavV2/SQLEditorTreeViewItem.tsx +++ b/apps/studio/components/layouts/SQLEditorLayout/SQLEditorNavV2/SQLEditorTreeViewItem.tsx @@ -1,7 +1,6 @@ import { PermissionAction } from '@supabase/shared-types/out/constants' import { IS_PLATFORM } from 'common' import { useParams } from 'common/hooks/useParams' -import { useIsSQLEditorTabsEnabled } from 'components/interfaces/App/FeaturePreview/FeaturePreviewContext' import { useSQLSnippetFolderContentsQuery } from 'data/content/sql-folder-contents-query' import { Snippet } from 'data/content/sql-folders-query' import { useCheckPermissions } from 'hooks/misc/useCheckPermissions' @@ -83,7 +82,6 @@ export const SQLEditorTreeViewItem = ({ const { profile } = useProfile() const { className, onClick } = getNodeProps() const snapV2 = useSqlEditorV2StateSnapshot() - const isSQLEditorTabsEnabled = useIsSQLEditorTabsEnabled() const isOwner = profile?.id === element?.metadata.owner_id const isSharedSnippet = element.metadata.visibility === 'project' @@ -262,13 +260,12 @@ export const SQLEditorTreeViewItem = ({ {}} onFocusCapture={(e) => e.stopPropagation()} > Open in new tab diff --git a/apps/studio/components/layouts/TableEditorLayout/EntityListItem.tsx b/apps/studio/components/layouts/TableEditorLayout/EntityListItem.tsx index d1e8269143b9c..62cea948bb687 100644 --- a/apps/studio/components/layouts/TableEditorLayout/EntityListItem.tsx +++ b/apps/studio/components/layouts/TableEditorLayout/EntityListItem.tsx @@ -10,7 +10,6 @@ import { MAX_EXPORT_ROW_COUNT_MESSAGE, } from 'components/grid/components/header/Header' import { parseSupaTable } from 'components/grid/SupabaseGrid.utils' -import { useIsTableEditorTabsEnabled } from 'components/interfaces/App/FeaturePreview/FeaturePreviewContext' import { formatTableRowsToSQL, getEntityLintDetails, @@ -70,11 +69,9 @@ const EntityListItem: ItemRenderer = ({ const snap = useTableEditorStateSnapshot() const { selectedSchema } = useQuerySchemaState() - // For tabs preview flag logic - const isTableEditorTabsEnabled = useIsTableEditorTabsEnabled() const tabId = createTabId(entity.type, { id: entity.id }) const tabs = useTabsStateSnapshot() - const isPreview = isTableEditorTabsEnabled ? tabs.previewTabId === tabId : false + const isPreview = tabs.previewTabId === tabId const isOpened = Object.values(tabs.tabsMap).some((tab) => tab.metadata?.tableId === entity.id) const isActive = Number(id) === entity.id diff --git a/apps/studio/components/layouts/TableEditorLayout/TableEditorMenu.tsx b/apps/studio/components/layouts/TableEditorLayout/TableEditorMenu.tsx index a306730b11407..84bd7f4f689ac 100644 --- a/apps/studio/components/layouts/TableEditorLayout/TableEditorMenu.tsx +++ b/apps/studio/components/layouts/TableEditorLayout/TableEditorMenu.tsx @@ -5,7 +5,6 @@ import { useEffect, useMemo, useState } from 'react' import { useParams } from 'common' import { useBreakpoint } from 'common/hooks/useBreakpoint' -import { useIsTableEditorTabsEnabled } from 'components/interfaces/App/FeaturePreview/FeaturePreviewContext' import { ProtectedSchemaModal } from 'components/interfaces/Database/ProtectedSchemaWarning' import EditorMenuListSkeleton from 'components/layouts/TableEditorLayout/EditorMenuListSkeleton' import AlertError from 'components/ui/AlertError' @@ -45,11 +44,10 @@ import EntityListItem from './EntityListItem' import { TableMenuEmptyState } from './TableMenuEmptyState' const TableEditorMenu = () => { - const { ref, id: _id } = useParams() + const { id: _id } = useParams() const id = _id ? Number(_id) : undefined const snap = useTableEditorStateSnapshot() const { selectedSchema, setSelectedSchema } = useQuerySchemaState() - const isTableEditorTabsEnabled = useIsTableEditorTabsEnabled() const isMobile = useBreakpoint() const [showModal, setShowModal] = useState(false) @@ -118,10 +116,10 @@ const TableEditorMenu = () => { const tableEditorTabsCleanUp = useTableEditorTabsCleanUp() useEffect(() => { // Clean up tabs + recent items for any tables that might have been removed outside of the dashboard session - if (isTableEditorTabsEnabled && entityTypes && !searchText) { + if (entityTypes && !searchText) { tableEditorTabsCleanUp({ schemas: [selectedSchema], entities: entityTypes }) } - }, [entityTypes, isTableEditorTabsEnabled, searchText, selectedSchema, tableEditorTabsCleanUp]) + }, [entityTypes, searchText, selectedSchema, tableEditorTabsCleanUp]) return ( <> diff --git a/apps/studio/components/layouts/Tabs/NewTab.tsx b/apps/studio/components/layouts/Tabs/NewTab.tsx index ba199aab48051..8afcfe3bd4d4e 100644 --- a/apps/studio/components/layouts/Tabs/NewTab.tsx +++ b/apps/studio/components/layouts/Tabs/NewTab.tsx @@ -6,7 +6,6 @@ import { useRouter } from 'next/router' import { toast } from 'sonner' import { useParams } from 'common' -import { TabsUpdateCallout } from 'components/interfaces/App/FeaturePreview/TableEditorTabs' import { SQL_TEMPLATES } from 'components/interfaces/SQLEditor/SQLEditor.queries' import { createSqlSnippetSkeletonV2 } from 'components/interfaces/SQLEditor/SQLEditor.utils' import { useSendEventMutation } from 'data/telemetry/send-event-mutation' @@ -114,7 +113,6 @@ export function NewTab() { return (
-
{actions.map((item, i) => ( diff --git a/apps/studio/components/layouts/Tabs/Tabs.tsx b/apps/studio/components/layouts/Tabs/Tabs.tsx index 66fb4b9b71538..847a3c11d4545 100644 --- a/apps/studio/components/layouts/Tabs/Tabs.tsx +++ b/apps/studio/components/layouts/Tabs/Tabs.tsx @@ -12,7 +12,6 @@ import { Plus, X } from 'lucide-react' import { useRouter } from 'next/router' import { useParams } from 'common' -import { TabsUpdateTooltip } from 'components/interfaces/App/FeaturePreview/TableEditorTabs' import { useAppStateSnapshot } from 'state/app-state' import { editorEntityTypes, useTabsStateSnapshot, type Tab } from 'state/tabs' import { @@ -173,43 +172,41 @@ export const EditorTabs = () => { {/* Non-draggable new tab */} {hasNewTab && ( - <> - + +
+ New +
+ { + e.preventDefault() + e.stopPropagation() + }} + className="ml-1 opacity-0 group-hover:opacity-100 hover:bg-200 rounded-sm cursor-pointer" + onMouseDown={(e) => { + e.preventDefault() + e.stopPropagation() + }} + onPointerDown={(e) => { + e.preventDefault() + e.stopPropagation() + handleClose('new') + }} > - -
- New -
- { - e.preventDefault() - e.stopPropagation() - }} - className="ml-1 opacity-0 group-hover:opacity-100 hover:bg-200 rounded-sm cursor-pointer" - onMouseDown={(e) => { - e.preventDefault() - e.stopPropagation() - }} - onPointerDown={(e) => { - e.preventDefault() - e.stopPropagation() - handleClose('new') - }} - > - - {' '} -
- - + + {' '} +
+ )} @@ -235,8 +232,6 @@ export const EditorTabs = () => {
- - diff --git a/apps/studio/components/layouts/editors/EditorBaseLayout.tsx b/apps/studio/components/layouts/editors/EditorBaseLayout.tsx index eafb111c3b0b5..9f0da404d7fb4 100644 --- a/apps/studio/components/layouts/editors/EditorBaseLayout.tsx +++ b/apps/studio/components/layouts/editors/EditorBaseLayout.tsx @@ -2,10 +2,6 @@ import { usePathname } from 'next/navigation' import { ComponentProps, ReactNode } from 'react' import { useParams } from 'common' -import { - useIsSQLEditorTabsEnabled, - useIsTableEditorTabsEnabled, -} from 'components/interfaces/App/FeaturePreview/FeaturePreviewContext' import { useTabsStateSnapshot } from 'state/tabs' import { cn } from 'ui' import { ProjectLayoutWithAuth } from '../ProjectLayout/ProjectLayout' @@ -26,12 +22,6 @@ export const EditorBaseLayout = ({ children, title, product, ...props }: Explore const editor = useEditorType() const tabs = useTabsStateSnapshot() - const isTableEditorTabsEnabled = useIsTableEditorTabsEnabled() - const isSQLEditorTabsEnabled = useIsSQLEditorTabsEnabled() - - const tableEditorTabsEnabled = editor === 'table' && isTableEditorTabsEnabled - const sqlEditorTabsEnabled = editor === 'sql' && isSQLEditorTabsEnabled - const hasNoOpenTabs = editor === 'table' ? tabs.openTabs.filter((x) => !x.startsWith('sql')).length === 0 : false const hideTabs = @@ -40,16 +30,14 @@ export const EditorBaseLayout = ({ children, title, product, ...props }: Explore return (
- {tableEditorTabsEnabled || sqlEditorTabsEnabled ? ( -
- {hideTabs ? : } -
- ) : null} +
+ {hideTabs ? : } +
{children}
diff --git a/apps/studio/pages/_app.tsx b/apps/studio/pages/_app.tsx index f8f95bfbb55a1..feb9b18b02643 100644 --- a/apps/studio/pages/_app.tsx +++ b/apps/studio/pages/_app.tsx @@ -109,6 +109,7 @@ function CustomApp({ Component, pageProps }: AppPropsWithLayout) { Supabase + {/* [Alaister]: This has to be an inline style tag here and not a separate component due to next/font */}