mirror of
https://github.com/supabase/supabase.git
synced 2026-10-14 13:49:09 +03:00
refactor again
This commit is contained in:
1 parent
40708d2702
commit
00d91d0af6
5 files changed
+212
-139
No files matched your search
@@ -1,7 +1,7 @@
|
||||
import { debounce } from 'lodash'
|
||||
import { Book, Save, X } from 'lucide-react'
|
||||
import { useCallback, useEffect, useState } from 'react'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { toast } from 'sonner'
|
||||
import { useForm } from 'react-hook-form'
|
||||
|
||||
import { useParams } from 'common'
|
||||
import {
|
||||
@@ -13,7 +13,7 @@ import { SqlRunButton } from 'components/interfaces/SQLEditor/UtilityPanel/RunBu
|
||||
import { useSqlTitleGenerateMutation } from 'data/ai/sql-title-mutation'
|
||||
import { QueryResponseError, useExecuteSqlMutation } from 'data/sql/execute-sql-mutation'
|
||||
import { useOrgAiOptInLevel } from 'hooks/misc/useOrgOptedIntoAi'
|
||||
import { useSelectedProject } from 'hooks/misc/useSelectedProject'
|
||||
import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject'
|
||||
import { BASE_PATH } from 'lib/constants'
|
||||
import { uuidv4 } from 'lib/helpers'
|
||||
import { useProfile } from 'lib/profile'
|
||||
@@ -28,9 +28,12 @@ import {
|
||||
CommandInput_Shadcn_,
|
||||
CommandItem_Shadcn_,
|
||||
CommandList_Shadcn_,
|
||||
FormField_Shadcn_,
|
||||
Form_Shadcn_,
|
||||
HoverCard_Shadcn_,
|
||||
HoverCardContent_Shadcn_,
|
||||
HoverCardTrigger_Shadcn_,
|
||||
Input_Shadcn_ as Input,
|
||||
Popover_Shadcn_,
|
||||
PopoverContent_Shadcn_,
|
||||
PopoverTrigger_Shadcn_,
|
||||
@@ -39,6 +42,7 @@ import {
|
||||
SheetHeader,
|
||||
SheetTitle,
|
||||
SQL_ICON,
|
||||
SheetDescription,
|
||||
} from 'ui'
|
||||
import { Admonition } from 'ui-patterns'
|
||||
import { containsUnknownFunction, isReadOnlySelect } from '../AIAssistantPanel/AIAssistant.utils'
|
||||
@@ -46,21 +50,45 @@ import AIEditor from '../AIEditor'
|
||||
import { ButtonTooltip } from '../ButtonTooltip'
|
||||
import { InlineLink } from '../InlineLink'
|
||||
import SqlWarningAdmonition from '../SqlWarningAdmonition'
|
||||
import type { EditorPanelProps } from './EditorPanel.types'
|
||||
|
||||
type Template = {
|
||||
name: string
|
||||
description: string
|
||||
content: string
|
||||
}
|
||||
|
||||
interface EditorPanelProps {
|
||||
open: boolean
|
||||
onClose: () => void
|
||||
initialValue?: string
|
||||
label?: string
|
||||
saveLabel?: string
|
||||
saveValue?: string
|
||||
onSave?: (value: string) => void
|
||||
onRunSuccess?: (value: any[]) => void
|
||||
onRunError?: (value: any) => void
|
||||
functionName?: string
|
||||
templates?: Template[]
|
||||
initialPrompt?: string
|
||||
onChange?: (value: string) => void
|
||||
}
|
||||
|
||||
export const EditorPanel = ({
|
||||
open,
|
||||
onClose,
|
||||
initialValue = '',
|
||||
label = 'SQL Editor',
|
||||
saveLabel = 'Run',
|
||||
label = '',
|
||||
saveLabel = 'Save',
|
||||
saveValue = '',
|
||||
onSave,
|
||||
onRunSuccess,
|
||||
onRunError,
|
||||
templates = [],
|
||||
initialPrompt = '',
|
||||
onChange,
|
||||
}: EditorPanelProps) => {
|
||||
const { ref } = useParams()
|
||||
const project = useSelectedProject()
|
||||
const { data: project } = useSelectedProjectQuery()
|
||||
const { profile } = useProfile()
|
||||
const snapV2 = useSqlEditorV2StateSnapshot()
|
||||
const { mutateAsync: generateSqlTitle } = useSqlTitleGenerateMutation()
|
||||
@@ -71,11 +99,15 @@ export const EditorPanel = ({
|
||||
const [results, setResults] = useState<undefined | any[]>(undefined)
|
||||
const [showWarning, setShowWarning] = useState<'hasWriteOperation' | 'hasUnknownFunctions'>()
|
||||
const [currentValue, setCurrentValue] = useState(initialValue)
|
||||
const [savedCode, setSavedCode] = useState<string>('')
|
||||
const [isPreviewingTemplate, setIsPreviewingTemplate] = useState(false)
|
||||
const [showResults, setShowResults] = useState(true)
|
||||
const [isTemplatesOpen, setIsTemplatesOpen] = useState(false)
|
||||
|
||||
const saveForm = useForm({
|
||||
defaultValues: {
|
||||
saveValue: saveValue || '',
|
||||
},
|
||||
})
|
||||
|
||||
const errorHeader = error?.formattedError?.split('\n')?.filter((x: string) => x.length > 0)?.[0]
|
||||
const errorContent =
|
||||
error?.formattedError
|
||||
@@ -86,14 +118,20 @@ export const EditorPanel = ({
|
||||
const { mutate: executeSql, isLoading: isExecuting } = useExecuteSqlMutation({
|
||||
onSuccess: async (res) => {
|
||||
setResults(res.result)
|
||||
if (onRunSuccess) {
|
||||
onRunSuccess(res.result)
|
||||
}
|
||||
},
|
||||
onError: (error) => {
|
||||
setError(error)
|
||||
setResults([])
|
||||
if (onRunError) {
|
||||
onRunError(error)
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
const onExecuteSql = (skipValidation = false) => {
|
||||
const onExecuteSql = async (skipValidation = false) => {
|
||||
setError(undefined)
|
||||
setShowWarning(undefined)
|
||||
|
||||
@@ -107,11 +145,6 @@ export const EditorPanel = ({
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if (onSave) {
|
||||
onSave(currentValue)
|
||||
}
|
||||
|
||||
executeSql({
|
||||
sql: suffixWithLimit(currentValue, 100),
|
||||
projectRef: project?.ref,
|
||||
@@ -133,28 +166,21 @@ export const EditorPanel = ({
|
||||
setIsTemplatesOpen(false)
|
||||
}
|
||||
|
||||
// Create a debounced version of the revert code function
|
||||
const debouncedRevertCode = useCallback(
|
||||
debounce(() => {
|
||||
setIsPreviewingTemplate(false)
|
||||
handleChange(savedCode)
|
||||
}, 300),
|
||||
[savedCode]
|
||||
)
|
||||
|
||||
// Cleanup debounce on unmount
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
debouncedRevertCode.cancel()
|
||||
}
|
||||
}, [debouncedRevertCode])
|
||||
|
||||
useEffect(() => {
|
||||
if (initialValue !== undefined && initialValue !== currentValue) {
|
||||
setCurrentValue(initialValue)
|
||||
setResults(undefined)
|
||||
setError(undefined)
|
||||
setShowWarning(undefined)
|
||||
}
|
||||
}, [initialValue])
|
||||
|
||||
useEffect(() => {
|
||||
saveForm.reset({
|
||||
saveValue: saveValue || '',
|
||||
})
|
||||
}, [saveValue, saveForm])
|
||||
|
||||
return (
|
||||
<Sheet open={open} onOpenChange={(open) => !open && onClose()}>
|
||||
<SheetContent
|
||||
@@ -162,7 +188,10 @@ export const EditorPanel = ({
|
||||
className="w-full sm:max-w-3xl flex flex-col h-full p-0 space-y-0 gap-0"
|
||||
>
|
||||
<SheetHeader className="flex shrink-0 items-center gap-x-3">
|
||||
<SheetTitle className="text-sm flex-1">{label}</SheetTitle>
|
||||
<div className="flex-1">
|
||||
<SheetTitle className="text-sm">SQL Editor</SheetTitle>
|
||||
{label && <SheetDescription className="text-sm">{label}</SheetDescription>}
|
||||
</div>
|
||||
<div className="flex gap-2 items-center">
|
||||
{templates.length > 0 && (
|
||||
<Popover_Shadcn_ open={isTemplatesOpen} onOpenChange={setIsTemplatesOpen}>
|
||||
@@ -371,6 +400,34 @@ export const EditorPanel = ({
|
||||
)}
|
||||
|
||||
<div className="flex items-center gap-2 justify-end px-5 py-4 w-full border-t shrink-0">
|
||||
{onSave && (
|
||||
<Form_Shadcn_ {...saveForm}>
|
||||
<form
|
||||
onSubmit={saveForm.handleSubmit((values) => {
|
||||
onSave(values.saveValue)
|
||||
})}
|
||||
className="flex items-center gap-2"
|
||||
>
|
||||
{saveValue && (
|
||||
<FormField_Shadcn_
|
||||
control={saveForm.control}
|
||||
name="saveValue"
|
||||
render={({ field }) => (
|
||||
<Input size="tiny" placeholder="Enter save value..." {...field} />
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
<Button
|
||||
size="tiny"
|
||||
type="default"
|
||||
htmlType="submit"
|
||||
disabled={!saveForm.formState.isDirty}
|
||||
>
|
||||
{saveLabel}
|
||||
</Button>
|
||||
</form>
|
||||
</Form_Shadcn_>
|
||||
)}
|
||||
<SqlRunButton
|
||||
isDisabled={isExecuting}
|
||||
isExecuting={isExecuting}
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
export type Template = {
|
||||
name: string
|
||||
description: string
|
||||
content: string
|
||||
}
|
||||
|
||||
export interface EditorPanelProps {
|
||||
open: boolean
|
||||
onClose: () => void
|
||||
initialValue?: string
|
||||
label?: string
|
||||
saveLabel?: string
|
||||
onSave?: (value: string) => void
|
||||
functionName?: string
|
||||
templates?: Template[]
|
||||
initialPrompt?: string
|
||||
onChange?: (value: string) => void
|
||||
}
|
||||
|
||||
export interface EditorPanelState {
|
||||
initialValue?: string
|
||||
label?: string
|
||||
saveLabel?: string
|
||||
templates?: Template[]
|
||||
initialPrompt?: string
|
||||
onSave?: (value: string) => void
|
||||
}
|
||||
@@ -14,7 +14,6 @@ import { useProjectContext } from 'components/layouts/ProjectLayout/ProjectConte
|
||||
import AlertError from 'components/ui/AlertError'
|
||||
import { DocsButton } from 'components/ui/DocsButton'
|
||||
import { EditorPanel } from 'components/ui/EditorPanel/EditorPanel'
|
||||
import type { EditorPanelState } from 'components/ui/EditorPanel/EditorPanel.types'
|
||||
import NoPermission from 'components/ui/NoPermission'
|
||||
import SchemaSelector from 'components/ui/SchemaSelector'
|
||||
import { GenericSkeletonLoader } from 'components/ui/ShimmeringLoader'
|
||||
@@ -73,10 +72,9 @@ const AuthPoliciesPage: NextPageWithLayout = () => {
|
||||
const [selectedTable, setSelectedTable] = useState<string>()
|
||||
const [showPolicyAiEditor, setShowPolicyAiEditor] = useState(false)
|
||||
const [selectedPolicyToEdit, setSelectedPolicyToEdit] = useState<PostgresPolicy>()
|
||||
|
||||
|
||||
// Local editor panel state
|
||||
const [editorPanelOpen, setEditorPanelOpen] = useState(false)
|
||||
const [editorPanelProps, setEditorPanelProps] = useState<EditorPanelState>({})
|
||||
|
||||
const { isSchemaLocked } = useIsProtectedSchema({ schema: schema, excludedSchemas: ['realtime'] })
|
||||
|
||||
@@ -146,43 +144,20 @@ const AuthPoliciesPage: NextPageWithLayout = () => {
|
||||
hasTables={tables.length > 0}
|
||||
isLocked={isSchemaLocked}
|
||||
onSelectCreatePolicy={(table: string) => {
|
||||
setSelectedTable(table)
|
||||
setSelectedPolicyToEdit(undefined)
|
||||
if (isInlineEditorEnabled) {
|
||||
setEditorPanelProps({
|
||||
initialValue: `create policy "replace_with_policy_name"
|
||||
on ${schema}.${table}
|
||||
for select
|
||||
to authenticated
|
||||
using (
|
||||
true -- Write your policy condition here
|
||||
);`,
|
||||
label: `Create new RLS policy on "${table}"`,
|
||||
saveLabel: 'Create policy',
|
||||
initialPrompt: `Create and name a entirely new RLS policy for the "${table}" table in the ${schema} schema. The policy should...`,
|
||||
})
|
||||
setEditorPanelOpen(true)
|
||||
} else {
|
||||
setSelectedTable(table)
|
||||
setShowPolicyAiEditor(true)
|
||||
}
|
||||
}}
|
||||
onSelectEditPolicy={(policy) => {
|
||||
setSelectedPolicyToEdit(policy)
|
||||
setSelectedTable(undefined)
|
||||
if (isInlineEditorEnabled) {
|
||||
const sql = generatePolicyUpdateSQL(policy)
|
||||
const templates = getGeneralPolicyTemplates(policy.schema, policy.table)
|
||||
setEditorPanelProps({
|
||||
initialValue: sql,
|
||||
label: `Edit policy "${policy.name}"`,
|
||||
saveLabel: 'Update policy',
|
||||
templates: templates.map((template) => ({
|
||||
name: template.templateName,
|
||||
description: template.description,
|
||||
content: template.statement,
|
||||
})),
|
||||
initialPrompt: `Update the policy with name "${policy.name}" in the ${policy.schema} schema on the ${policy.table} table. It should...`,
|
||||
})
|
||||
setEditorPanelOpen(true)
|
||||
} else {
|
||||
setSelectedPolicyToEdit(policy)
|
||||
setShowPolicyAiEditor(true)
|
||||
}
|
||||
}}
|
||||
@@ -202,11 +177,58 @@ const AuthPoliciesPage: NextPageWithLayout = () => {
|
||||
}}
|
||||
authContext="database"
|
||||
/>
|
||||
|
||||
|
||||
<EditorPanel
|
||||
open={editorPanelOpen}
|
||||
onClose={() => setEditorPanelOpen(false)}
|
||||
{...editorPanelProps}
|
||||
onClose={() => {
|
||||
setEditorPanelOpen(false)
|
||||
setSelectedPolicyToEdit(undefined)
|
||||
setSelectedTable(undefined)
|
||||
}}
|
||||
onRunSuccess={() => {
|
||||
setEditorPanelOpen(false)
|
||||
setSelectedPolicyToEdit(undefined)
|
||||
setSelectedTable(undefined)
|
||||
}}
|
||||
initialValue={
|
||||
selectedPolicyToEdit
|
||||
? generatePolicyUpdateSQL(selectedPolicyToEdit)
|
||||
: selectedTable
|
||||
? `create policy "replace_with_policy_name"
|
||||
on ${schema}.${selectedTable}
|
||||
for select
|
||||
to authenticated
|
||||
using (
|
||||
true -- Write your policy condition here
|
||||
);`
|
||||
: ''
|
||||
}
|
||||
label={
|
||||
selectedPolicyToEdit
|
||||
? 'RLS policies are just SQL statements that you can alter'
|
||||
: selectedTable
|
||||
? `Create new RLS policy on "${selectedTable}"`
|
||||
: ''
|
||||
}
|
||||
initialPrompt={
|
||||
selectedPolicyToEdit
|
||||
? `Update the policy with name "${selectedPolicyToEdit.name}" in the ${selectedPolicyToEdit.schema} schema on the ${selectedPolicyToEdit.table} table. It should...`
|
||||
: selectedTable
|
||||
? `Create and name a entirely new RLS policy for the "${selectedTable}" table in the ${schema} schema. The policy should...`
|
||||
: ''
|
||||
}
|
||||
templates={
|
||||
selectedPolicyToEdit
|
||||
? getGeneralPolicyTemplates(
|
||||
selectedPolicyToEdit.schema,
|
||||
selectedPolicyToEdit.table
|
||||
).map((template) => ({
|
||||
name: template.templateName,
|
||||
description: template.description,
|
||||
content: template.statement,
|
||||
}))
|
||||
: []
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -8,7 +8,6 @@ import DatabaseLayout from 'components/layouts/DatabaseLayout/DatabaseLayout'
|
||||
import DefaultLayout from 'components/layouts/DefaultLayout'
|
||||
import { ScaffoldContainer, ScaffoldSection } from 'components/layouts/Scaffold'
|
||||
import { EditorPanel } from 'components/ui/EditorPanel/EditorPanel'
|
||||
import type { EditorPanelState } from 'components/ui/EditorPanel/EditorPanel.types'
|
||||
import { FormHeader } from 'components/ui/Forms/FormHeader'
|
||||
import NoPermission from 'components/ui/NoPermission'
|
||||
import { DatabaseFunction } from 'data/database-functions/database-functions-query'
|
||||
@@ -20,29 +19,19 @@ const DatabaseFunctionsPage: NextPageWithLayout = () => {
|
||||
const [showCreateFunctionForm, setShowCreateFunctionForm] = useState(false)
|
||||
const [showDeleteFunctionForm, setShowDeleteFunctionForm] = useState(false)
|
||||
const isInlineEditorEnabled = useIsInlineEditorEnabled()
|
||||
|
||||
|
||||
// Local editor panel state
|
||||
const [editorPanelOpen, setEditorPanelOpen] = useState(false)
|
||||
const [editorPanelProps, setEditorPanelProps] = useState<EditorPanelState>({})
|
||||
const [selectedFunctionForEditor, setSelectedFunctionForEditor] = useState<
|
||||
DatabaseFunction | undefined
|
||||
>()
|
||||
|
||||
const canReadFunctions = useCheckPermissions(PermissionAction.TENANT_SQL_ADMIN_READ, 'functions')
|
||||
const isPermissionsLoaded = usePermissionsLoaded()
|
||||
|
||||
const createFunction = () => {
|
||||
if (isInlineEditorEnabled) {
|
||||
setEditorPanelProps({
|
||||
initialValue: `create function function_name()
|
||||
returns void
|
||||
language plpgsql
|
||||
as $$
|
||||
begin
|
||||
-- Write your function logic here
|
||||
end;
|
||||
$$;`,
|
||||
label: 'Create new database function',
|
||||
saveLabel: 'Create function',
|
||||
initialPrompt: 'Create a new database function that...',
|
||||
})
|
||||
setSelectedFunctionForEditor(undefined)
|
||||
setEditorPanelOpen(true)
|
||||
} else {
|
||||
setSelectedFunction(undefined)
|
||||
@@ -52,12 +41,7 @@ $$;`,
|
||||
|
||||
const editFunction = (fn: DatabaseFunction) => {
|
||||
if (isInlineEditorEnabled) {
|
||||
setEditorPanelProps({
|
||||
initialValue: fn.complete_statement,
|
||||
label: `Edit function "${fn.name}"`,
|
||||
saveLabel: 'Update function',
|
||||
initialPrompt: `Update the database function "${fn.name}" to...`,
|
||||
})
|
||||
setSelectedFunctionForEditor(fn)
|
||||
setEditorPanelOpen(true)
|
||||
} else {
|
||||
setSelectedFunction(fn)
|
||||
@@ -101,11 +85,39 @@ $$;`,
|
||||
visible={showDeleteFunctionForm}
|
||||
setVisible={setShowDeleteFunctionForm}
|
||||
/>
|
||||
|
||||
|
||||
<EditorPanel
|
||||
open={editorPanelOpen}
|
||||
onClose={() => setEditorPanelOpen(false)}
|
||||
{...editorPanelProps}
|
||||
onRunSuccess={() => {
|
||||
setEditorPanelOpen(false)
|
||||
setSelectedFunctionForEditor(undefined)
|
||||
}}
|
||||
onClose={() => {
|
||||
setEditorPanelOpen(false)
|
||||
setSelectedFunctionForEditor(undefined)
|
||||
}}
|
||||
initialValue={
|
||||
selectedFunctionForEditor
|
||||
? selectedFunctionForEditor.complete_statement
|
||||
: `create function function_name()
|
||||
returns void
|
||||
language plpgsql
|
||||
as $$
|
||||
begin
|
||||
-- Write your function logic here
|
||||
end;
|
||||
$$;`
|
||||
}
|
||||
label={
|
||||
selectedFunctionForEditor
|
||||
? `Edit function "${selectedFunctionForEditor.name}"`
|
||||
: 'Create new database function'
|
||||
}
|
||||
initialPrompt={
|
||||
selectedFunctionForEditor
|
||||
? `Update the database function "${selectedFunctionForEditor.name}" to...`
|
||||
: 'Create a new database function that...'
|
||||
}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
|
||||
@@ -11,7 +11,6 @@ import DatabaseLayout from 'components/layouts/DatabaseLayout/DatabaseLayout'
|
||||
import DefaultLayout from 'components/layouts/DefaultLayout'
|
||||
import { ScaffoldContainer, ScaffoldSection } from 'components/layouts/Scaffold'
|
||||
import { EditorPanel } from 'components/ui/EditorPanel/EditorPanel'
|
||||
import type { EditorPanelState } from 'components/ui/EditorPanel/EditorPanel.types'
|
||||
import { FormHeader } from 'components/ui/Forms/FormHeader'
|
||||
import NoPermission from 'components/ui/NoPermission'
|
||||
import { useCheckPermissions, usePermissionsLoaded } from 'hooks/misc/useCheckPermissions'
|
||||
@@ -23,25 +22,17 @@ const TriggersPage: NextPageWithLayout = () => {
|
||||
const [selectedTrigger, setSelectedTrigger] = useState<PostgresTrigger>()
|
||||
const [showCreateTriggerForm, setShowCreateTriggerForm] = useState<boolean>(false)
|
||||
const [showDeleteTriggerForm, setShowDeleteTriggerForm] = useState<boolean>(false)
|
||||
|
||||
|
||||
// Local editor panel state
|
||||
const [editorPanelOpen, setEditorPanelOpen] = useState(false)
|
||||
const [editorPanelProps, setEditorPanelProps] = useState<EditorPanelState>({})
|
||||
const [selectedTriggerForEditor, setSelectedTriggerForEditor] = useState<PostgresTrigger>()
|
||||
|
||||
const canReadTriggers = useCheckPermissions(PermissionAction.TENANT_SQL_ADMIN_READ, 'triggers')
|
||||
const isPermissionsLoaded = usePermissionsLoaded()
|
||||
|
||||
const createTrigger = () => {
|
||||
if (isInlineEditorEnabled) {
|
||||
setEditorPanelProps({
|
||||
initialValue: `create trigger trigger_name
|
||||
after insert or update or delete on table_name
|
||||
for each row
|
||||
execute function function_name();`,
|
||||
label: 'Create new database trigger',
|
||||
saveLabel: 'Create trigger',
|
||||
initialPrompt: 'Create a new database trigger that...',
|
||||
})
|
||||
setSelectedTriggerForEditor(undefined)
|
||||
setEditorPanelOpen(true)
|
||||
} else {
|
||||
setSelectedTrigger(undefined)
|
||||
@@ -51,13 +42,7 @@ execute function function_name();`,
|
||||
|
||||
const editTrigger = (trigger: PostgresTrigger) => {
|
||||
if (isInlineEditorEnabled) {
|
||||
const sql = generateTriggerCreateSQL(trigger)
|
||||
setEditorPanelProps({
|
||||
initialValue: sql,
|
||||
label: `Edit trigger "${trigger.name}"`,
|
||||
saveLabel: 'Update trigger',
|
||||
initialPrompt: `Update the database trigger "${trigger.name}" to...`,
|
||||
})
|
||||
setSelectedTriggerForEditor(trigger)
|
||||
setEditorPanelOpen(true)
|
||||
} else {
|
||||
setSelectedTrigger(trigger)
|
||||
@@ -102,11 +87,35 @@ execute function function_name();`,
|
||||
visible={showDeleteTriggerForm}
|
||||
setVisible={setShowDeleteTriggerForm}
|
||||
/>
|
||||
|
||||
|
||||
<EditorPanel
|
||||
open={editorPanelOpen}
|
||||
onClose={() => setEditorPanelOpen(false)}
|
||||
{...editorPanelProps}
|
||||
onRunSuccess={() => {
|
||||
setEditorPanelOpen(false)
|
||||
setSelectedTriggerForEditor(undefined)
|
||||
}}
|
||||
onClose={() => {
|
||||
setEditorPanelOpen(false)
|
||||
setSelectedTriggerForEditor(undefined)
|
||||
}}
|
||||
initialValue={
|
||||
selectedTriggerForEditor
|
||||
? generateTriggerCreateSQL(selectedTriggerForEditor)
|
||||
: `create trigger trigger_name
|
||||
after insert or update or delete on table_name
|
||||
for each row
|
||||
execute function function_name();`
|
||||
}
|
||||
label={
|
||||
selectedTriggerForEditor
|
||||
? `Edit trigger "${selectedTriggerForEditor.name}"`
|
||||
: 'Create new database trigger'
|
||||
}
|
||||
initialPrompt={
|
||||
selectedTriggerForEditor
|
||||
? `Update the database trigger "${selectedTriggerForEditor.name}" to...`
|
||||
: 'Create a new database trigger that...'
|
||||
}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
|
||||
Reference in new issue
Block a user