mirror of
https://github.com/supabase/supabase.git
synced 2026-10-08 19:05:06 +03:00
## Context Related to Explorer/Notebooks - this PR adds the functionality to add / remove cells Separately - am thinking we can shift a lot of the "cell update" logic into notebook-state, mainly so that each UI component doesn't need to be aware of the notebook's `cells` but just its own cell. I'll do it separately though to prevent bloating this PR, already left comments where i think can be refactored <img width="250" alt="image" src="https://github.com/user-attachments/assets/91aae5f9-07b9-4327-8e21-8e9d71098aa6" /> <img width="250" alt="image" src="https://github.com/user-attachments/assets/677de208-5c52-4155-90c6-bc0879070693" /> <img width="250" alt="image" src="https://github.com/user-attachments/assets/17c3dae7-87bc-40bb-bfa0-15df101006ce" /> <img width="1091" height="262" alt="image" src="https://github.com/user-attachments/assets/a09c3d23-696a-4b55-a1f8-4602e56a60dc" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## New Features - Add query and Markdown cells directly within notebooks. - Move, remove, and reorder cells using drag-and-drop or cell controls. - Add cells from empty states and notebook toolbar actions. - Edit Markdown cells, mark edits as complete, and see placeholders for empty content. ## Improvements - Cell controls and hover interactions are more consistent and responsive. - Moving cells is disabled at the top or bottom of a notebook. - Sample cells now use standardized content and formatting. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
94 lines
2.7 KiB
TypeScript
94 lines
2.7 KiB
TypeScript
import { useRouter } from 'next/router'
|
|
|
|
import { createMarkdownCellSkeleton, createQueryCellSkeleton } from './utils'
|
|
import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
|
|
import { generateUuid } from '@/lib/api/snippets.browser'
|
|
import { useProfile } from '@/lib/profile'
|
|
import { useExplorerQueryStateSnapshot } from '@/state/explorer-query'
|
|
import { useNotebooksStateSnapshot } from '@/state/notebooks/notebooks-state'
|
|
import { type Notebook } from '@/state/notebooks/types'
|
|
import { Notebooks } from '@/types'
|
|
|
|
export const useCreateNotebook = () => {
|
|
const router = useRouter()
|
|
const { profile } = useProfile()
|
|
const { data: project } = useSelectedProjectQuery()
|
|
const notebooksSnap = useNotebooksStateSnapshot()
|
|
|
|
const createNotebook = ({
|
|
id: idOverride,
|
|
name,
|
|
cells,
|
|
}: { id?: string; name?: string; cells?: Notebooks.Content['cells'] } = {}) => {
|
|
if (!profile) return console.error('Profile is required')
|
|
if (!project) return console.error('Project is required')
|
|
|
|
const sampleMdCell1 = createMarkdownCellSkeleton({
|
|
content: `
|
|
# Title
|
|
A brief description on what this notebook is about
|
|
`.trim(),
|
|
})
|
|
const sampleMdCell2 = createMarkdownCellSkeleton({
|
|
content: `
|
|
## Section
|
|
This is a sample paragraph to demonstrate the Markdown cells
|
|
1. List item 1
|
|
2. List item 2
|
|
3. List item 3
|
|
`.trim(),
|
|
})
|
|
const sampleQueryCell = createQueryCellSkeleton({ sql: 'select * from colors;' })
|
|
|
|
// [Joshen] Just adding sample data to play around with, keep for now - clean up at the end
|
|
const DEFAULT_CELLS = [
|
|
sampleMdCell1,
|
|
sampleMdCell2,
|
|
sampleQueryCell,
|
|
] as Notebooks.Content['cells']
|
|
|
|
const id = idOverride ?? generateUuid()
|
|
|
|
const notebook: Notebook = {
|
|
id,
|
|
type: 'notebook',
|
|
name: name ?? 'New Notebook',
|
|
description: '',
|
|
visibility: 'project',
|
|
favorite: false,
|
|
content: {
|
|
schema_version: 1,
|
|
cells: cells ?? DEFAULT_CELLS,
|
|
},
|
|
owner_id: profile.id,
|
|
project_id: project.id,
|
|
}
|
|
|
|
notebooksSnap.addNotebook({ projectRef: project.ref, notebook })
|
|
notebooksSnap.addNeedsSaving(notebook.id)
|
|
|
|
router.push(`/project/${project.ref}/explorer/notebook/${notebook.id}`)
|
|
}
|
|
|
|
return { createNotebook }
|
|
}
|
|
|
|
export const useCreateQuery = () => {
|
|
const router = useRouter()
|
|
const { data: project } = useSelectedProjectQuery()
|
|
const querySnap = useExplorerQueryStateSnapshot()
|
|
|
|
const createQuery = () => {
|
|
if (!project) return console.error('Project is required')
|
|
|
|
const id = generateUuid()
|
|
querySnap.createDraft({ id, projectRef: project.ref })
|
|
|
|
router.push(`/project/${project.ref}/explorer/query/${id}`)
|
|
|
|
return id
|
|
}
|
|
|
|
return { createQuery }
|
|
}
|