mirror of
https://github.com/supabase/supabase.git
synced 2026-10-11 12:25:05 +03:00
158 lines
4.5 KiB
TypeScript
158 lines
4.5 KiB
TypeScript
import ActionBar from 'components/interfaces/TableGridEditor/SidePanelEditor/ActionBar'
|
|
import { useState } from 'react'
|
|
import { Checkbox, Input, Listbox, SidePanel, Accordion, Form } from 'ui'
|
|
import { TableOption, Table } from './types'
|
|
|
|
export type WrapperTableEditorProps = {
|
|
visible: boolean
|
|
onCancel: () => void
|
|
onSave: (values: any) => void
|
|
|
|
tables: Table[]
|
|
}
|
|
|
|
const WrapperTableEditor = ({ visible, onCancel, onSave, tables }: WrapperTableEditorProps) => {
|
|
const [selectedTableIndex, setSelectedTableIndex] = useState<string>('')
|
|
|
|
const selectedTable = selectedTableIndex === '' ? undefined : tables[parseInt(selectedTableIndex)]
|
|
|
|
const onSubmit = (values: any) => {
|
|
onSave(values)
|
|
}
|
|
|
|
return (
|
|
<SidePanel
|
|
key="WrapperTableEditor"
|
|
size="medium"
|
|
visible={visible}
|
|
onCancel={onCancel}
|
|
header={<span>Edit foreign table</span>}
|
|
customFooter={
|
|
<ActionBar
|
|
backButtonLabel="Cancel"
|
|
applyButtonLabel="Save"
|
|
formId="wrapper-table-editor-form"
|
|
closePanel={onCancel}
|
|
/>
|
|
}
|
|
>
|
|
<SidePanel.Content>
|
|
<div className="mt-4 space-y-6">
|
|
<Listbox
|
|
label="Select a target the table will point to"
|
|
value={selectedTableIndex}
|
|
onChange={(value) => setSelectedTableIndex(value)}
|
|
>
|
|
<Listbox.Option key="empty" value="" label="---">
|
|
---
|
|
</Listbox.Option>
|
|
|
|
{tables.map((table, i) => {
|
|
return (
|
|
<Listbox.Option key={String(i)} value={String(i)} label={table.label}>
|
|
<div className="flex items-center gap-2">{table.label}</div>
|
|
</Listbox.Option>
|
|
)
|
|
})}
|
|
</Listbox>
|
|
|
|
{selectedTable && <TableForm table={selectedTable} onSubmit={onSubmit} />}
|
|
</div>
|
|
</SidePanel.Content>
|
|
</SidePanel>
|
|
)
|
|
}
|
|
|
|
export default WrapperTableEditor
|
|
|
|
const Option = ({ option }: { option: TableOption }) => {
|
|
return (
|
|
<Input
|
|
key={option.name}
|
|
id={option.name}
|
|
name={option.name}
|
|
label={option.label}
|
|
placeholder={option.placeholder ?? ''}
|
|
defaultValue={option.defaultValue ?? ''}
|
|
required={option.required ?? false}
|
|
/>
|
|
)
|
|
}
|
|
|
|
const TableForm = ({ table, onSubmit }: { table: Table; onSubmit: (values: any) => void }) => {
|
|
const requiredOptions =
|
|
table.options.filter((option) => option.editable && option.required && !option.defaultValue) ??
|
|
[]
|
|
const optionalOptions =
|
|
table.options.filter(
|
|
(option) => option.editable && (!option.required || option.defaultValue)
|
|
) ?? []
|
|
|
|
const initialValues = Object.fromEntries(
|
|
[
|
|
['table_name', ''],
|
|
['columns', []],
|
|
].concat(table.options.map((option) => [option.name, option.defaultValue ?? '']))
|
|
)
|
|
|
|
return (
|
|
<Form
|
|
id="wrapper-table-editor-form"
|
|
initialValues={initialValues}
|
|
// validate={validate}
|
|
onSubmit={onSubmit}
|
|
>
|
|
{() => (
|
|
<div className="space-y-4">
|
|
<Input
|
|
id="table-name"
|
|
name="table_name"
|
|
label="Table name"
|
|
descriptionText="The name of the local table table you will query after the wrapper is enabled."
|
|
required
|
|
/>
|
|
|
|
{requiredOptions.map((option) => (
|
|
<Option key={option.name} option={option} />
|
|
))}
|
|
|
|
<div className="space-y-2">
|
|
<label className="block text-sm break-all text-scale-1100">Columns</label>
|
|
|
|
<div>
|
|
{table.availableColumns.map((column, k) => (
|
|
<Checkbox
|
|
key={k}
|
|
id={column.name}
|
|
name="columns"
|
|
value={column.name}
|
|
label={`${column.name} (${column.type})`}
|
|
/>
|
|
))}
|
|
</div>
|
|
</div>
|
|
|
|
{optionalOptions.length > 0 && (
|
|
<Accordion
|
|
className="text-sm"
|
|
justified={false}
|
|
openBehaviour="multiple"
|
|
type="default"
|
|
chevronAlign="left"
|
|
size="small"
|
|
bordered={false}
|
|
iconPosition="left"
|
|
>
|
|
<Accordion.Item id="1" header="Optional Fields">
|
|
{optionalOptions.map((option) => (
|
|
<Option key={option.name} option={option} />
|
|
))}
|
|
</Accordion.Item>
|
|
</Accordion>
|
|
)}
|
|
</div>
|
|
)}
|
|
</Form>
|
|
)
|
|
}
|