Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export const ExperimentalTokenDropdown = ({ onCreateToken }: ExperimentalTokenDr
<Button
variant="primary"
aria-label="Choose token scope"
className="rounded-l-none px-[4px] py-[5px]"
className="-ml-px rounded-l-none px-[4px] py-[5px] focus-visible:z-10"
icon={<ChevronDown />}
/>
</DropdownMenuTrigger>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ export const NewTokenButton = ({ onCreateToken }: NewAccessTokenButtonProps) =>
return (
<>
<div className="flex items-center">
<Button className="rounded-r-none px-3" onClick={() => setVisible(true)}>
<Button
className="rounded-r-none px-3 hover:z-10 focus-visible:z-10"
onClick={() => setVisible(true)}
>
Generate new token
</Button>
<ExperimentalTokenDropdown onCreateToken={onCreateToken} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ export const NewScopedTokenSheet = ({ onCreateExperimentalToken }: NewScopedToke
<Sheet open={isOpen} onOpenChange={handleOpenChange}>
<div className="flex items-center">
<SheetTrigger asChild>
<Button variant="primary" className="rounded-r-none px-3">
<Button variant="primary" className="rounded-r-none px-3 hover:z-10 focus-visible:z-10">
Generate new token
</Button>
</SheetTrigger>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export const CustomEmailTemplateRestrictionAdmonition = () => {
<Button
asChild
variant="default"
className="flex-1 rounded-r-none px-3 @lg:flex-none hover:z-10"
className="flex-1 rounded-r-none px-3 @lg:flex-none hover:z-10 focus-visible:z-10"
>
<Link href={`/project/${projectRef}/auth/smtp`}>Set up SMTP</Link>
</Button>
Expand All @@ -37,7 +37,7 @@ export const CustomEmailTemplateRestrictionAdmonition = () => {
<Button
variant="default"
aria-label="More email template editing options"
className="shrink-0 rounded-l-none px-[4px] py-[5px] -ml-px"
className="shrink-0 rounded-l-none px-[4px] py-[5px] -ml-px focus-visible:z-10"
icon={<ChevronDown />}
/>
</DropdownMenuTrigger>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@ export const ReplicationPipelineStatus = () => {
<Button
size="tiny"
variant="default"
className="rounded-r-none hover:z-2"
className="rounded-r-none hover:z-10 focus-visible:z-10"
icon={<RotateCcw />}
disabled={isAnyRestartInProgress || showDisabledState || isPipelineError}
loading={isAnyRestartInProgress}
Expand All @@ -435,7 +435,7 @@ export const ReplicationPipelineStatus = () => {
<Button
variant="default"
icon={<ChevronDown />}
className="w-7 rounded-l-none -ml-px"
className="w-7 rounded-l-none -ml-px focus-visible:z-10"
disabled={showDisabledState || isPipelineError}
/>
</DropdownMenuTrigger>
Expand Down
19 changes: 3 additions & 16 deletions apps/studio/components/interfaces/Explorer/ExplorerHome.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import { untrustedSql } from '@supabase/pg-meta'
import { MessageCirclePlus, NotebookText, SquareCode } from 'lucide-react'
import { useState } from 'react'

import { useCreateNotebook } from './hooks'
import { useCreateNotebook, useCreateQuery } from './hooks'
import { ActionCard } from '@/components/layouts/Tabs/ActionCard'
import { AssistantChatForm } from '@/components/ui/AIAssistantPanel/AssistantChatForm'
import { generateUuid } from '@/lib/api/snippets.browser'
import { AssistantModel } from '@/state/ai-assistant-state'

export const ExplorerHome = () => {
const { createNotebook } = useCreateNotebook()
const { createQuery } = useCreateQuery()

const [value, setValue] = useState<string>('')
const [selectedModel, setSelectedModal] = useState<AssistantModel>('gpt-5.4-nano')
Expand Down Expand Up @@ -52,19 +51,7 @@ export const ExplorerHome = () => {
title="Run SQL"
description="Write and run an ad-hoc query"
bgColor="bg-blue-500"
onClick={() =>
createNotebook({
name: 'SQL query',
cells: [
{
_tag: 'database_cell',
id: generateUuid(),
unchecked_sql: untrustedSql(''),
row_limit: 100,
},
],
})
}
onClick={createQuery}
/>
</div>
</section>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { useParams } from 'common'
import { useContext, useEffect } from 'react'

import { explorerQueryState } from '@/state/explorer-query'
import { TabsStateContext } from '@/state/tabs'

/**
* Owns local query-draft cleanup and close confirmation for every Explorer page,
* including Explorer home where no individual query editor is mounted.
*/
export const ExplorerQueryTabCoordinator = () => {
const { ref } = useParams()
const tabs = useContext(TabsStateContext)

useEffect(() => {
return tabs.registerTabTypeHandler('query', {
confirmClose: (queryTabs) => {
const populatedDraftCount = queryTabs.filter((tab) => {
const queryId = tab.metadata?.queryId
if (!ref || !queryId) return false

explorerQueryState.restoreDraft({ id: queryId, projectRef: ref })

return explorerQueryState.drafts[queryId]?.uncheckedSql.trim().length > 0
}).length

if (populatedDraftCount === 0) return null

return {
title: populatedDraftCount === 1 ? 'Discard query?' : 'Discard queries?',
description:
populatedDraftCount === 1
? 'This ad-hoc query is stored only in this browser. Closing the tab will discard it.'
: `These ${populatedDraftCount} ad-hoc queries are stored only in this browser. Closing their tabs will discard them.`,
}
},
onClose: (tab) => {
const queryId = tab.metadata?.queryId
if (ref && queryId) explorerQueryState.removeDraft({ id: queryId, projectRef: ref })
},
})
}, [ref, tabs])

return null
}
14 changes: 0 additions & 14 deletions apps/studio/components/interfaces/Explorer/NotebookEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import {
} from '@dnd-kit/sortable'
import { useParams } from 'common'
import { Notebook, NotebookText, Play, Save } from 'lucide-react'
import { useEffect, useEffectEvent } from 'react'
import { AiIconAnimation, Button } from 'ui'
import { EmptyStatePresentational } from 'ui-patterns/EmptyStatePresentational'

Expand Down Expand Up @@ -63,19 +62,6 @@ export const NotebookEditor = () => {
snap.updateCells({ id, cells: arrayMove([...cells], oldIndex, newIndex) })
}

const registerTab = useEffectEvent(() => {
if (!id) return
tabs.addTab({
id: createTabId('notebook', { id }),
type: 'notebook',
label: name ?? 'New Notebook',
metadata: { notebookId: id },
isPreview: false,
})
})

useEffect(() => registerTab(), [id])

return (
<div className="flex flex-col h-full bg-surface-100">
<ExplorerToolbar className="px-4">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,34 +18,29 @@ import {
TooltipTrigger,
} from 'ui'
import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
import { type Snapshot } from 'valtio'

import { ExplorerToolbarAction } from '../ExplorerToolbar'
import { type QueryResult } from '../types'
import { type QueryChartConfig, type QueryDisplay, type QueryResult } from '../types'
import { checkHasNonPositiveValues } from '@/components/ui/QueryBlock/QueryBlock.utils'
import { type DatabaseCell as DatabaseCellSchema } from '@/data/content/notebooks/notebook-schema'
import { useCurrentNotebook, useNotebooksStateSnapshot } from '@/state/notebooks/notebooks-state'

interface DisplaySettingsButtonProps {
cell: Snapshot<DatabaseCellSchema>
display: QueryDisplay
result?: QueryResult
columns: string[]
disabled: boolean
onChange: (display: QueryDisplay) => void
}

// [Joshen] TODO support multiple y axis charts

export const DisplaySettingsButton = ({
cell,
display,
result,
columns,
disabled,
onChange,
}: DisplaySettingsButtonProps) => {
const snap = useNotebooksStateSnapshot()
const currentNotebook = useCurrentNotebook()
const cells = currentNotebook?.notebook.content?.cells ?? []

const { view, chart } = cell
const { view, chart } = display
const {
type = 'bar',
x_column,
Expand All @@ -66,44 +61,22 @@ export const DisplaySettingsButton = ({
}, [hasNonPositiveValues, result, y_columns.length])

const onChangeView = (view: 'table' | 'chart') => {
const notebookId = currentNotebook?.notebook.id
if (!notebookId) return

const nextCells = cells.map((c) =>
c.id === cell.id && c._tag === 'database_cell' ? { ...c, view } : c
)
snap.updateCells({ id: notebookId, cells: nextCells })
onChange({ ...display, view })
}

const onUpdateChartConfig = (
payload:
| { type: 'bar' | 'line' }
| { x_column: string }
| { y_columns: string[] }
| { cumulative: boolean }
| { show_labels: boolean }
| { scale: 'linear' | 'log' }
) => {
const notebookId = currentNotebook?.notebook.id
if (!notebookId) return

const nextCells = cells.map((c) => {
if (c.id !== cell.id || c._tag !== 'database_cell') return c

return {
...c,
chart: {
type: c.chart?.type ?? 'bar',
x_column: c.chart?.x_column ?? '',
y_columns: c.chart?.y_columns ?? [],
cumulative: c.chart?.cumulative ?? false,
scale: c.chart?.scale ?? 'linear',
show_labels: c.chart?.show_labels ?? false,
...payload,
},
}
const onUpdateChartConfig = (payload: Partial<QueryChartConfig>) => {
onChange({
...display,
chart: {
type: chart?.type ?? 'bar',
x_column: chart?.x_column ?? '',
y_columns: chart?.y_columns ?? [],
cumulative: chart?.cumulative ?? false,
scale: chart?.scale ?? 'linear',
show_labels: chart?.show_labels ?? false,
...payload,
},
})
snap.updateCells({ id: notebookId, cells: nextCells })
}

const resetToLinearScale = useEffectEvent(() => {
Expand Down Expand Up @@ -230,7 +203,7 @@ export const DisplaySettingsButton = ({
</SelectItem>
</TooltipTrigger>
{!canToggleLogScale && (
<TooltipContent side="right">
<TooltipContent side="left">
{y_columns.length === 0
? 'Select a column for the Y axis first'
: 'Data contains zero or negative values'}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
import { useMemo } from 'react'
import { Chart, ChartBar, ChartCard, ChartContent, ChartLine } from 'ui-patterns/Chart'
import { type Snapshot } from 'valtio'

import { type QueryResult } from '../types'
import { type QueryChartConfig, type QueryResult } from '../types'
import NoDataPlaceholder from '@/components/ui/Charts/NoDataPlaceholder'
import { formatLogTick, getCumulativeResults } from '@/components/ui/QueryBlock/QueryBlock.utils'
import { type DatabaseCell as DatabaseCellSchema } from '@/data/content/notebooks/notebook-schema'

interface QueryResultChartProps {
cell: Snapshot<DatabaseCellSchema>
chart?: QueryChartConfig
result?: QueryResult
}

Expand All @@ -21,8 +19,7 @@ const toChartValue = (value: unknown): string | number => {
return String(value)
}

export const QueryResultChart = ({ cell, result }: QueryResultChartProps) => {
const { chart } = cell
export const QueryResultChart = ({ chart, result }: QueryResultChartProps) => {
const { type, x_column, y_columns = [], cumulative, show_labels, scale } = chart ?? {}

const hasConfig = !!x_column && y_columns.length > 0
Expand Down
Loading
Loading