diff --git a/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreview.constants.tsx b/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreview.constants.tsx index ceadbd396bf..c2b2c54f742 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 4fa0a7dcf67..bef4199d7cc 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 94bc324361f..f7a047d003b 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 08a82c3f74c..228da9d8b4d 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 ee053af8657..00000000000 --- 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 1a83d1e70dd..00000000000 --- 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/SQLEditor/RenameQueryModal.tsx b/apps/studio/components/interfaces/SQLEditor/RenameQueryModal.tsx index 2f062081911..35af13d8543 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 054174f05f3..fb4e0914772 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 11ef4f28fa6..bb7625b410a 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 0fbf052477c..00000000000 --- 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 2bfb205ed15..debbd89ef68 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 08ec744a22f..a29a158fc05 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 50e1839b986..52936211e7e 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 ac33ba4ff1d..41a6434e197 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 3c887f9ac36..0d6d6f1fcd9 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 895eaee2bb2..3633fdf5b74 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 d1e8269143b..62cea948bb6 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 a306730b114..84bd7f4f689 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 ba199aab480..8afcfe3bd4d 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 66fb4b9b715..847a3c11d45 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 eafb111c3b0..9f0da404d7f 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/project/[ref]/editor/[id].tsx b/apps/studio/pages/project/[ref]/editor/[id].tsx index 8e4bab3f158..7409c843e69 100644 --- a/apps/studio/pages/project/[ref]/editor/[id].tsx +++ b/apps/studio/pages/project/[ref]/editor/[id].tsx @@ -1,7 +1,6 @@ import { useEffect } from 'react' import { useParams } from 'common' -import { useIsTableEditorTabsEnabled } from 'components/interfaces/App/FeaturePreview/FeaturePreviewContext' import { TableGridEditor } from 'components/interfaces/TableGridEditor/TableGridEditor' import DefaultLayout from 'components/layouts/DefaultLayout' import { EditorBaseLayout } from 'components/layouts/editors/EditorBaseLayout' @@ -30,11 +29,9 @@ const TableEditorPage: NextPageWithLayout = () => { * - selectedTable changes (when a new table is loaded) * - id changes (when URL parameter changes) */ - const isTableEditorTabsEnabled = useIsTableEditorTabsEnabled() useEffect(() => { - // tabs preview flag logic - if (isTableEditorTabsEnabled && selectedTable && projectRef) { + if (selectedTable && projectRef) { const tabId = createTabId(selectedTable.entity_type, { id: selectedTable.id }) if (!store.tabsMap[tabId]) { store.addTab({ @@ -52,7 +49,7 @@ const TableEditorPage: NextPageWithLayout = () => { store.makeTabActive(tabId) } } - }, [selectedTable, id, projectRef, isTableEditorTabsEnabled]) + }, [selectedTable, id, projectRef]) return } diff --git a/apps/studio/pages/project/[ref]/editor/index.tsx b/apps/studio/pages/project/[ref]/editor/index.tsx index b970f2e90a1..55797c6e53d 100644 --- a/apps/studio/pages/project/[ref]/editor/index.tsx +++ b/apps/studio/pages/project/[ref]/editor/index.tsx @@ -1,14 +1,13 @@ +import { useRouter } from 'next/router' +import { useEffect } from 'react' + import { useParams } from 'common' -import { useIsTableEditorTabsEnabled } from 'components/interfaces/App/FeaturePreview/FeaturePreviewContext' -import EmptyState from 'components/interfaces/TableGridEditor/EmptyState' import SidePanelEditor from 'components/interfaces/TableGridEditor/SidePanelEditor/SidePanelEditor' import DefaultLayout from 'components/layouts/DefaultLayout' import { EditorBaseLayout } from 'components/layouts/editors/EditorBaseLayout' import TableEditorLayout from 'components/layouts/TableEditorLayout/TableEditorLayout' import TableEditorMenu from 'components/layouts/TableEditorLayout/TableEditorMenu' import { NewTab } from 'components/layouts/Tabs/NewTab' -import { useRouter } from 'next/router' -import { useEffect } from 'react' import { useAppStateSnapshot } from 'state/app-state' import { editorEntityTypes, useTabsStateSnapshot } from 'state/tabs' import type { NextPageWithLayout } from 'types' @@ -18,7 +17,6 @@ const TableEditorPage: NextPageWithLayout = () => { const { ref: projectRef } = useParams() const tabStore = useTabsStateSnapshot() const appSnap = useAppStateSnapshot() - const isTableEditorTabsEnabled = useIsTableEditorTabsEnabled() const onTableCreated = (table: { id: number }) => { router.push(`/project/${projectRef}/editor/${table.id}`) @@ -26,25 +24,22 @@ const TableEditorPage: NextPageWithLayout = () => { useEffect(() => { const lastOpenedTab = appSnap.dashboardHistory.editor - if (isTableEditorTabsEnabled) { - const lastTabId = tabStore.openTabs.find((id) => - editorEntityTypes.table.includes(tabStore.tabsMap[id]?.type) - ) - if (lastOpenedTab !== undefined) { - router.push(`/project/${projectRef}/editor/${appSnap.dashboardHistory.editor}`) - } else if (lastTabId) { - // Handle redirect to last opened table tab, or last table tab - const lastTab = tabStore.tabsMap[lastTabId] - if (lastTab) router.push(`/project/${projectRef}/editor/${lastTab.metadata?.tableId}`) - } - } else if (lastOpenedTab) { + + const lastTabId = tabStore.openTabs.find((id) => + editorEntityTypes.table.includes(tabStore.tabsMap[id]?.type) + ) + if (lastOpenedTab !== undefined) { router.push(`/project/${projectRef}/editor/${appSnap.dashboardHistory.editor}`) + } else if (lastTabId) { + // Handle redirect to last opened table tab, or last table tab + const lastTab = tabStore.tabsMap[lastTabId] + if (lastTab) router.push(`/project/${projectRef}/editor/${lastTab.metadata?.tableId}`) } - }, [isTableEditorTabsEnabled]) + }, []) return ( <> - {isTableEditorTabsEnabled ? : } + ) diff --git a/apps/studio/pages/project/[ref]/sql/[id].tsx b/apps/studio/pages/project/[ref]/sql/[id].tsx index 40d8b604b6a..36acdb1ef89 100644 --- a/apps/studio/pages/project/[ref]/sql/[id].tsx +++ b/apps/studio/pages/project/[ref]/sql/[id].tsx @@ -2,7 +2,6 @@ import { useRouter } from 'next/router' import { useEffect } from 'react' import { useParams } from 'common/hooks/useParams' -import { useIsSQLEditorTabsEnabled } from 'components/interfaces/App/FeaturePreview/FeaturePreviewContext' import { SQLEditor } from 'components/interfaces/SQLEditor/SQLEditor' import DefaultLayout from 'components/layouts/DefaultLayout' import { EditorBaseLayout } from 'components/layouts/editors/EditorBaseLayout' @@ -26,7 +25,6 @@ const SqlEditor: NextPageWithLayout = () => { const tabs = useTabsStateSnapshot() const appSnap = useAppStateSnapshot() const snapV2 = useSqlEditorV2StateSnapshot() - const isSqlEditorTabsEnabled = useIsSQLEditorTabsEnabled() const allSnippets = useSnippets(ref!) const snippet = allSnippets.find((x) => x.id === id) @@ -72,23 +70,21 @@ const SqlEditor: NextPageWithLayout = () => { // Watch for route changes useEffect(() => { - if (isSqlEditorTabsEnabled) { - if (!router.isReady || !id || id === 'new') return + if (!router.isReady || !id || id === 'new') return - const tabId = createTabId('sql', { id }) - const snippet = allSnippets.find((x) => x.id === id) + const tabId = createTabId('sql', { id }) + const snippet = allSnippets.find((x) => x.id === id) - tabs.addTab({ - id: tabId, - type: 'sql', - label: snippet?.name || 'Untitled Query', - metadata: { - sqlId: id, - name: snippet?.name, - }, - }) - } - }, [router.isReady, id, isSqlEditorTabsEnabled]) + tabs.addTab({ + id: tabId, + type: 'sql', + label: snippet?.name || 'Untitled Query', + metadata: { + sqlId: id, + name: snippet?.name, + }, + }) + }, [router.isReady, id]) if (snippetMissing || invalidId) { return ( @@ -99,31 +95,27 @@ const SqlEditor: NextPageWithLayout = () => { title={`Unable to find snippet with ID ${id}`} description="This snippet doesn't exist in your project" > - {isSqlEditorTabsEnabled && ( - <> - {!!tabId ? ( - - ) : ( - - )} - + {!!tabId ? ( + + ) : ( + )}
diff --git a/apps/studio/pages/project/[ref]/sql/index.tsx b/apps/studio/pages/project/[ref]/sql/index.tsx index 633f87e8738..b76303b8010 100644 --- a/apps/studio/pages/project/[ref]/sql/index.tsx +++ b/apps/studio/pages/project/[ref]/sql/index.tsx @@ -1,12 +1,12 @@ +import { useRouter } from 'next/router' +import { useEffect } from 'react' + import { useParams } from 'common' -import { useIsSQLEditorTabsEnabled } from 'components/interfaces/App/FeaturePreview/FeaturePreviewContext' import DefaultLayout from 'components/layouts/DefaultLayout' import { EditorBaseLayout } from 'components/layouts/editors/EditorBaseLayout' import SQLEditorLayout from 'components/layouts/SQLEditorLayout/SQLEditorLayout' import { SQLEditorMenu } from 'components/layouts/SQLEditorLayout/SQLEditorMenu' import { NewTab } from 'components/layouts/Tabs/NewTab' -import { useRouter } from 'next/router' -import { useEffect } from 'react' import { useAppStateSnapshot } from 'state/app-state' import { useTabsStateSnapshot } from 'state/tabs' import type { NextPageWithLayout } from 'types' @@ -16,26 +16,20 @@ const TableEditorPage: NextPageWithLayout = () => { const { ref: projectRef } = useParams() const store = useTabsStateSnapshot() const appSnap = useAppStateSnapshot() - const isSqlEditorTabsEnabled = useIsSQLEditorTabsEnabled() useEffect(() => { - if (!isSqlEditorTabsEnabled) { - // Redirect to /new if not using tabs - router.push(`/project/${projectRef}/sql/new`) - } else { - // Handle redirect to last opened snippet tab, or last snippet tab - const lastOpenedTab = appSnap.dashboardHistory.sql - const lastTabId = store.openTabs.find((id) => store.tabsMap[id]?.type === 'sql') - if (lastOpenedTab !== undefined) { - router.push(`/project/${projectRef}/sql/${appSnap.dashboardHistory.sql}`) - } else if (lastTabId) { - const lastTab = store.tabsMap[lastTabId] - if (lastTab) router.push(`/project/${projectRef}/sql/${lastTab.id.replace('sql-', '')}`) - } + // Handle redirect to last opened snippet tab, or last snippet tab + const lastOpenedTab = appSnap.dashboardHistory.sql + const lastTabId = store.openTabs.find((id) => store.tabsMap[id]?.type === 'sql') + if (lastOpenedTab !== undefined) { + router.push(`/project/${projectRef}/sql/${appSnap.dashboardHistory.sql}`) + } else if (lastTabId) { + const lastTab = store.tabsMap[lastTabId] + if (lastTab) router.push(`/project/${projectRef}/sql/${lastTab.id.replace('sql-', '')}`) } - }, [isSqlEditorTabsEnabled]) + }, []) - return isSqlEditorTabsEnabled ? : null + return } TableEditorPage.getLayout = (page) => ( diff --git a/apps/studio/pages/project/[ref]/sql/quickstarts.tsx b/apps/studio/pages/project/[ref]/sql/quickstarts.tsx index bdeffe57588..2b69bbc2512 100644 --- a/apps/studio/pages/project/[ref]/sql/quickstarts.tsx +++ b/apps/studio/pages/project/[ref]/sql/quickstarts.tsx @@ -2,7 +2,6 @@ import { useParams } from 'next/navigation' import { useRouter } from 'next/router' import { useEffect } from 'react' -import { useIsSQLEditorTabsEnabled } from 'components/interfaces/App/FeaturePreview/FeaturePreviewContext' import SQLQuickstarts from 'components/interfaces/SQLEditor/SQLTemplates/SQLQuickstarts' import DefaultLayout from 'components/layouts/DefaultLayout' import { EditorBaseLayout } from 'components/layouts/editors/EditorBaseLayout' @@ -16,25 +15,20 @@ const SqlQuickstarts: NextPageWithLayout = () => { const { ref } = useParams<{ ref: string }>() const tabs = useTabsStateSnapshot() - const isSqlEditorTabsEnabled = useIsSQLEditorTabsEnabled() - useEffect(() => { - if (isSqlEditorTabsEnabled) { - if (!router.isReady) return + if (!router.isReady) return - const tabId = createTabId('sql', { id: 'quickstarts' }) - - tabs.addTab({ - id: tabId, - type: 'sql', - label: 'Quickstarts', - metadata: { - sqlId: 'quickstarts', - name: 'quickstarts', - }, - }) - } - }, [router.isReady, isSqlEditorTabsEnabled, ref]) + const tabId = createTabId('sql', { id: 'quickstarts' }) + tabs.addTab({ + id: tabId, + type: 'sql', + label: 'Quickstarts', + metadata: { + sqlId: 'quickstarts', + name: 'quickstarts', + }, + }) + }, [router.isReady, ref]) return } diff --git a/apps/studio/pages/project/[ref]/sql/templates.tsx b/apps/studio/pages/project/[ref]/sql/templates.tsx index 45920a90c96..2e219edaa52 100644 --- a/apps/studio/pages/project/[ref]/sql/templates.tsx +++ b/apps/studio/pages/project/[ref]/sql/templates.tsx @@ -2,7 +2,6 @@ import { useParams } from 'next/navigation' import { useRouter } from 'next/router' import { useEffect } from 'react' -import { useIsSQLEditorTabsEnabled } from 'components/interfaces/App/FeaturePreview/FeaturePreviewContext' import SQLTemplates from 'components/interfaces/SQLEditor/SQLTemplates/SQLTemplates' import DefaultLayout from 'components/layouts/DefaultLayout' import { EditorBaseLayout } from 'components/layouts/editors/EditorBaseLayout' @@ -16,25 +15,20 @@ const SqlTemplates: NextPageWithLayout = () => { const { ref } = useParams<{ ref: string }>() const tabs = useTabsStateSnapshot() - const isSqlEditorTabsEnabled = useIsSQLEditorTabsEnabled() - useEffect(() => { - if (isSqlEditorTabsEnabled) { - if (!router.isReady) return + if (!router.isReady) return - const tabId = createTabId('sql', { id: 'templates' }) - - tabs.addTab({ - id: tabId, - type: 'sql', - label: 'Templates', - metadata: { - sqlId: 'templates', - name: 'templates', - }, - }) - } - }, [router.isReady, isSqlEditorTabsEnabled, ref]) + const tabId = createTabId('sql', { id: 'templates' }) + tabs.addTab({ + id: tabId, + type: 'sql', + label: 'Templates', + metadata: { + sqlId: 'templates', + name: 'templates', + }, + }) + }, [router.isReady, ref]) return } diff --git a/e2e/studio/features/sql-editor.spec.ts b/e2e/studio/features/sql-editor.spec.ts index efb523b4183..b437c0a2f23 100644 --- a/e2e/studio/features/sql-editor.spec.ts +++ b/e2e/studio/features/sql-editor.spec.ts @@ -1,11 +1,11 @@ import { expect } from '@playwright/test' +import { env } from '../env.config' import { test } from '../utils/test' import { toUrl } from '../utils/to-url' -import { env } from '../env.config' test.describe('SQL Editor', () => { test('should check if SQL editor can run simple commands', async ({ page }) => { - await page.goto(toUrl(`/project/${env.PROJECT_REF}/sql`)) + await page.goto(toUrl(`/project/${env.PROJECT_REF}/sql/new?skip=true`)) const editor = page.getByRole('code').nth(0)