mirror of
https://github.com/supabase/supabase.git
synced 2026-10-10 20:05:06 +03:00
## Summary Step 2 of the SQL Editor testability plan. `SQLEditorContext` already wrapped the Monaco refs and exposed a few semantic imperative helpers (`getEditorSql`, `clearHighlights`, `applyErrorHighlight`, `refocusEditor`, …). This finishes that abstraction so no hook or controller touches `editorRef.current`/`diffEditorRef.current` directly anymore — they only call the port. The port is what will let Step 3's test harness inject a real in-memory editor adapter instead of mocking Monaco; production wires it to the real Monaco refs, unchanged. - Extends the context value with two semantic controllers, backed by the existing refs: - `editor: EditorController` — `isReady`, `getValue`, `getSelectionStartLine`, `getSql` (today's `getEditorSql`), `replaceAll` (wraps the repeated `executeEdits(...)` pattern), `focus`, `revealLineInCenter`, `highlightErrorLine` (today's `applyErrorHighlight`), `clearHighlights`. - `diff: DiffController` — `isMounted`, `getModifiedValue`, `setDiff` (the diff-sync effect body), `attach` (today's `handleDiffEditorMount`). - Migrates every touch point off raw refs onto the port: `useSqlEditorExecution`, `usePrettifyQuery`, `useSqlEditorShortcuts`, `SQLEditorControllers`' `readEditorSql`, and `useSqlEditorAi`'s `acceptAiHandler`/`drainDiffRequest`/`handleDiffEditorMount`/diff-sync effect. - `SQLEditorEditorPanel.tsx` is intentionally left untouched — it wires the raw refs into the real Monaco/DiffEditor React components for rendering, which isn't decision logic to abstract. Behavior-preserving. ## Test plan - [x] `pnpm --filter studio typecheck` - [x] `pnpm test:studio -- SQLEditor` (265 tests passing) - [x] `pnpm --filter studio run lint:ratchet`
Writing components
Where to create your components
- For components that declare the general structure and layout of a page:
/components/layouts/xxx
- For components that are tightly coupled to a specific interface:
/components/interfaces/xxx
- For components that are meant to be reusable across multiple pages:
/components/ui/xxx
- Note: We're gradually moving files out of the
to-be-cleanedfolder into the respective folders as we refactor
Component structure
- If a component has constants and utility methods that are tightly coupled to itself, keep them close to the component and enclose them in a folder with an
index.tsxas an entry point - Otherwise it can just be a file on its own
- For example:
-
components/ui - SampleComponentA - SampleComponentA.tsx - SampleComponentA.constants.ts - SampleComponentA.utils.ts - SampleComponentA.types.ts - index.ts - SampleComponentB.tsx
-
Template for building components
// Declare the prop types of your component
interface ComponentAProps {
sampleProp: string
}
// Name your component accordingly
const ComponentA = ({ sampleProp }: ComponentAProps) => {
return <div>ComponentA: {sampleProp}</div>
}
export default ComponentA