Files
supabase/studio/components/interfaces/Database/Functions/FunctionsList/FunctionList.tsx
T
Ivan Vasilov 76db9f27b3 Migrate dropdowns to use the new Dropdown component (#17427)
* Remove unneeded component.

* Update the dropdown content to support size prop (medium by default). Add space-x-2 to the dropdown item. Add flex to DropdownTrigger so that it's more vertically centered.

* Migrate Insert row dropdown in the TableEditor.

* Refactor UserDropdown to use the new Dropdown from shadcn.

* Migrate the ColumnMenu to use the new dropdown.

* Migrate the rest of the dropdowns.

* Remove the size prop and set the w-64 as default.

* Fix build errors.

* More dropdown fixes.

* More fixes.

* More fixes to various dropdowns.

* Remove the flex from the DropdownTrigger and add it in where it's needed.

* Snapshot.

* Remove keys on dropdown separators.

* Fix the dropdown in the SQL editor.

* Minor type fix.

* Remove space-x-2 from DropdownMenuItem and add it to each item where it's needed.

* Remove the space from the dropdown item.

* Fix a build error.

* Fix the item text in some of the dropdowns.

* Remove duplicate CSS from all dropdown items.

* The SubMenuContent text should be lighter to match MenuContent.

* Fix various CSS issues.

* Revert "Remove unneeded component."

This reverts commit ef606f6695.

* Fix migrated CSS classes.

* Last round of feedback fixes.
2023-09-26 15:29:07 +02:00

161 lines
5.5 KiB
TypeScript

import * as Tooltip from '@radix-ui/react-tooltip'
import { PermissionAction } from '@supabase/shared-types/out/constants'
import { includes, noop } from 'lodash'
import { observer } from 'mobx-react-lite'
import { useRouter } from 'next/router'
import {
Button,
DropdownMenuContent_Shadcn_,
DropdownMenuItem_Shadcn_,
DropdownMenuTrigger_Shadcn_,
DropdownMenu_Shadcn_,
IconEdit3,
IconFileText,
IconMoreVertical,
IconTrash,
} from 'ui'
import { useProjectContext } from 'components/layouts/ProjectLayout/ProjectContext'
import Table from 'components/to-be-cleaned/Table'
import { useCheckPermissions, useStore } from 'hooks'
interface FunctionListProps {
schema: string
filterString: string
isLocked: boolean
editFunction: (fn: any) => void
deleteFunction: (fn: any) => void
}
const FunctionList = ({
schema,
filterString,
isLocked,
editFunction = noop,
deleteFunction = noop,
}: FunctionListProps) => {
const router = useRouter()
const { meta } = useStore()
const { project: selectedProject } = useProjectContext()
const functions = meta.functions.list()
const filteredFunctions = functions.filter((x: any) =>
includes(x.name.toLowerCase(), filterString.toLowerCase())
)
const _functions = filteredFunctions.filter((x) => x.schema == schema)
const isApiDocumentAvailable = schema == 'public'
const projectRef = selectedProject?.ref
const canUpdateFunctions = useCheckPermissions(
PermissionAction.TENANT_SQL_ADMIN_WRITE,
'functions'
)
if (_functions.length === 0 && filterString.length === 0) {
return (
<Table.tr key={schema}>
<Table.td colSpan={4}>
<p className="text-sm text-foreground">No functions created yet</p>
<p className="text-sm text-light">
There are no functions found in the schema "{schema}"
</p>
</Table.td>
</Table.tr>
)
}
if (_functions.length === 0 && filterString.length > 0) {
return (
<Table.tr key={schema}>
<Table.td colSpan={4}>
<p className="text-sm text-foreground">No results found</p>
<p className="text-sm text-light">
Your search for "{filterString}" did not return any results
</p>
</Table.td>
</Table.tr>
)
}
return (
<>
{_functions.map((x) => (
<Table.tr key={x.id}>
<Table.td className="truncate">
<p>{x.name}</p>
</Table.td>
<Table.td className="hidden md:table-cell md:overflow-auto">
<p>{x.argument_types}</p>
</Table.td>
<Table.td className="hidden lg:table-cell">
<p>{x.return_type}</p>
</Table.td>
<Table.td className="text-right">
{!isLocked && (
<div className="flex items-center justify-end">
{canUpdateFunctions ? (
<DropdownMenu_Shadcn_>
<DropdownMenuTrigger_Shadcn_>
<Button asChild type="default" icon={<IconMoreVertical />}>
<span></span>
</Button>
</DropdownMenuTrigger_Shadcn_>
<DropdownMenuContent_Shadcn_ side="left">
{isApiDocumentAvailable && (
<DropdownMenuItem_Shadcn_
className="space-x-2"
onClick={() => router.push(`/project/${projectRef}/api?rpc=${x.name}`)}
>
<IconFileText size="tiny" />
<p className="text">Client API docs</p>
</DropdownMenuItem_Shadcn_>
)}
<DropdownMenuItem_Shadcn_
className="space-x-2"
onClick={() => editFunction(x)}
>
<IconEdit3 size="tiny" />
<p className="text">Edit function</p>
</DropdownMenuItem_Shadcn_>
<DropdownMenuItem_Shadcn_
className="space-x-2"
onClick={() => deleteFunction(x)}
>
<IconTrash stroke="red" size="tiny" />
<p className="text">Delete function</p>
</DropdownMenuItem_Shadcn_>
</DropdownMenuContent_Shadcn_>
</DropdownMenu_Shadcn_>
) : (
<Tooltip.Root delayDuration={0}>
<Tooltip.Trigger asChild>
<Button disabled type="default" icon={<IconMoreVertical />} />
</Tooltip.Trigger>
<Tooltip.Portal>
<Tooltip.Content side="left">
<Tooltip.Arrow className="radix-tooltip-arrow" />
<div
className={[
'rounded bg-scale-100 py-1 px-2 leading-none shadow',
'border border-scale-200',
].join(' ')}
>
<span className="text-xs text-foreground">
You need additional permissions to update functions
</span>
</div>
</Tooltip.Content>
</Tooltip.Portal>
</Tooltip.Root>
)}
</div>
)}
</Table.td>
</Table.tr>
))}
</>
)
}
export default observer(FunctionList)