diff --git a/apps/studio/components/interfaces/Auth/RedirectUrls/RedirectUrlList.tsx b/apps/studio/components/interfaces/Auth/RedirectUrls/RedirectUrlList.tsx
index 6e66f48cea1..938b838df17 100644
--- a/apps/studio/components/interfaces/Auth/RedirectUrls/RedirectUrlList.tsx
+++ b/apps/studio/components/interfaces/Auth/RedirectUrls/RedirectUrlList.tsx
@@ -1,77 +1,41 @@
import { noop } from 'lodash'
-import { Globe } from 'lucide-react'
+import { Button } from 'ui'
import { EmptyListState } from 'components/ui/States'
-import { Checkbox_Shadcn_ } from 'ui'
-import { ValueContainer } from './ValueContainer'
+import ValueContainer from './ValueContainer'
+import { Globe, Trash } from 'lucide-react'
interface RedirectUrlListProps {
- allowList: string[]
+ URI_ALLOW_LIST_ARRAY: string[]
canUpdate: boolean
- selectedUrls: string[]
- onSelectUrl: (urls: string[]) => void
+ onSelectUrlToDelete: (url: string) => void
}
-export const RedirectUrlList = ({
- allowList,
- selectedUrls,
- onSelectUrl = noop,
+const RedirectUrlList = ({
+ URI_ALLOW_LIST_ARRAY,
+ canUpdate,
+ onSelectUrlToDelete = noop,
}: RedirectUrlListProps) => {
- // [Joshen] One for next time: maybe shift this into a reusable logic since it
- // seems like we can use this in multiple places for future
- const onClickUrl = (event: any, url: string) => {
- if (event.shiftKey) {
- const urlIdx = allowList.indexOf(url)
- const idxLatest = allowList.indexOf(selectedUrls[selectedUrls.length - 1])
-
- const newSelectedUrls =
- urlIdx > idxLatest
- ? allowList.slice(idxLatest + 1, urlIdx + 1)
- : allowList.slice(urlIdx, idxLatest)
-
- const urlsNotSelectedYet = newSelectedUrls.filter((x) => !selectedUrls.includes(x))
-
- if (urlsNotSelectedYet.length > 0) {
- onSelectUrl([
- ...selectedUrls,
- ...(urlIdx > idxLatest ? newSelectedUrls : newSelectedUrls.reverse()),
- ])
- } else {
- const urlsToRemove = newSelectedUrls.concat([selectedUrls[selectedUrls.length - 1]])
- onSelectUrl(selectedUrls.filter((x) => !urlsToRemove.includes(x)))
- }
- } else {
- const isSelected = selectedUrls.includes(url)
- const newSelectedUrls = isSelected
- ? selectedUrls.filter((selectedUrl) => selectedUrl !== url)
- : [...selectedUrls, url]
- onSelectUrl(newSelectedUrls)
- }
- }
-
return (
- {allowList.length > 0 ? (
- <>
- {allowList.map((url) => {
- const isSelected = selectedUrls.includes(url)
- return (
-
onClickUrl(e, url)}>
-
-
-
-
-
-
-
{url}
-
- onClickUrl(e, url)} />
-
-
-
- )
- })}
- >
+ {URI_ALLOW_LIST_ARRAY.length > 0 ? (
+ URI_ALLOW_LIST_ARRAY.map((url) => {
+ return (
+
+
+
+
+
+ {url}
+
+ {canUpdate && (
+ } onClick={() => onSelectUrlToDelete(url)}>
+ Remove
+
+ )}
+
+ )
+ })
) : (
)
}
+
+export default RedirectUrlList
diff --git a/apps/studio/components/interfaces/Auth/RedirectUrls/RedirectUrls.tsx b/apps/studio/components/interfaces/Auth/RedirectUrls/RedirectUrls.tsx
index 1a59c673269..de9f7208475 100644
--- a/apps/studio/components/interfaces/Auth/RedirectUrls/RedirectUrls.tsx
+++ b/apps/studio/components/interfaces/Auth/RedirectUrls/RedirectUrls.tsx
@@ -1,12 +1,11 @@
import { PermissionAction } from '@supabase/shared-types/out/constants'
-import { ExternalLink, Trash } from 'lucide-react'
+import { useParams } from 'common'
+import { ExternalLink } from 'lucide-react'
import Link from 'next/link'
import { useMemo, useState } from 'react'
import { toast } from 'sonner'
import { object, string } from 'yup'
-import { Label } from '@ui/components/shadcn/ui/label'
-import { useParams } from 'common'
import { ButtonTooltip } from 'components/ui/ButtonTooltip'
import { FormHeader } from 'components/ui/Forms/FormHeader'
import { HorizontalShimmerWithIcon } from 'components/ui/Shimmers/Shimmers'
@@ -20,17 +19,15 @@ import {
Button,
DialogSectionSeparator,
Form,
+ Input,
Modal,
WarningIcon,
} from 'ui'
-import { Input } from 'ui-patterns/DataInputs/Input'
import { urlRegex } from '../Auth.constants'
-import { RedirectUrlList } from './RedirectUrlList'
-import { ValueContainer } from './ValueContainer'
+import RedirectUrlList from './RedirectUrlList'
+import ValueContainer from './ValueContainer'
-const MAX_URLS_LENGTH = 2 * 1024
-
-export const RedirectUrls = () => {
+const RedirectUrls = () => {
const { ref: projectRef } = useParams()
const {
data: authConfig,
@@ -48,8 +45,7 @@ export const RedirectUrls = () => {
}, [authConfig?.URI_ALLOW_LIST])
const [open, setOpen] = useState(false)
- const [openRemoveSelected, setOpenRemoveSelected] = useState(false)
- const [selectedUrls, setSelectedUrls] = useState
([])
+ const [selectedUrlToDelete, setSelectedUrlToDelete] = useState()
const canUpdateConfig = useCheckPermissions(PermissionAction.UPDATE, 'custom_config_gotrue')
@@ -68,7 +64,7 @@ export const RedirectUrls = () => {
const payloadString = payload.toString()
- if (payloadString.length > MAX_URLS_LENGTH) {
+ if (payloadString.length > 2 * 1024) {
return toast.error('Too many redirect URLs, please remove some or try to use wildcards')
}
@@ -86,25 +82,21 @@ export const RedirectUrls = () => {
)
}
- const onConfirmDeleteUrl = async (urls?: string[]) => {
- if (!urls || urls.length === 0) return
+ const onConfirmDeleteUrl = async (url?: string) => {
+ if (!url) return
// Remove selectedUrl from array and update
- const payload = URI_ALLOW_LIST_ARRAY.filter((url: string) => !selectedUrls.includes(url))
- const payloadString = payload.join(',')
- if (payloadString.length > MAX_URLS_LENGTH) {
- return toast.error('Too many redirect URLs, please remove some or try to use wildcards')
- }
+ const payload = URI_ALLOW_LIST_ARRAY.filter((e: string) => e !== url)
+
updateAuthConfig(
- { projectRef: projectRef!, config: { URI_ALLOW_LIST: payloadString } },
+ { projectRef: projectRef!, config: { URI_ALLOW_LIST: payload.toString() } },
{
onError: (error) => {
- toast.error(`Failed to remove URL(s): ${error?.message}`)
+ toast.error(`Failed to remove URL: ${error?.message}`)
},
onSuccess: () => {
- setSelectedUrls([])
- setOpenRemoveSelected(false)
- toast.success('Successfully removed URL(s)')
+ setSelectedUrlToDelete(undefined)
+ toast.success('Successfully removed URL')
},
}
)
@@ -118,51 +110,27 @@ export const RedirectUrls = () => {
description={`URLs that auth providers are permitted to redirect to post authentication. Wildcards are allowed, for example, https://*.domain.com`}
/>
- {selectedUrls.length > 0 ? (
- <>
-
- }
- onClick={() => (selectedUrls.length > 0 ? setOpenRemoveSelected(true) : null)}
- >
- Remove ({selectedUrls.length})
-
- >
- ) : (
- <>
- }>
-
- Documentation
-
-
- setOpen(true)}
- tooltip={{
- content: {
- side: 'bottom',
- text: 'You need additional permissions to update redirect URLs',
- },
- }}
- >
- Add URL
-
- >
- )}
+ }>
+
+ Documentation
+
+
+ setOpen(true)}
+ tooltip={{
+ content: {
+ side: 'bottom',
+ text: 'You need additional permissions to update redirect URLs',
+ },
+ }}
+ >
+ Add URL
+
{isLoading && (
@@ -184,10 +152,9 @@ export const RedirectUrls = () => {
)}
{isSuccess && (
)}
{
{() => {
return (
<>
-
-
-
+
+
@@ -232,27 +198,18 @@ export const RedirectUrls = () => {
{
- setSelectedUrls([])
- setOpenRemoveSelected(false)
- }}
+ size="small"
+ visible={selectedUrlToDelete !== undefined}
+ header="Remove URL"
+ onCancel={() => setSelectedUrlToDelete(undefined)}
>
- Are you sure you want to remove the following URLs?
+ Are you sure you want to remove{' '}
+ {selectedUrlToDelete}?
-
- {selectedUrls.map((url, index) => (
- -
- {url}
-
- ))}
-
- These URLs will no longer work with your authentication configuration.
+ This URL will no longer work with your authentication configuration.
@@ -261,10 +218,7 @@ export const RedirectUrls = () => {
block
type="default"
size="medium"
- onClick={() => {
- setSelectedUrls([])
- setOpenRemoveSelected(false)
- }}
+ onClick={() => setSelectedUrlToDelete(undefined)}
>
Cancel
@@ -273,7 +227,7 @@ export const RedirectUrls = () => {
size="medium"
type="warning"
loading={isUpdatingConfig}
- onClick={() => onConfirmDeleteUrl(selectedUrls)}
+ onClick={() => onConfirmDeleteUrl(selectedUrlToDelete)}
>
{isUpdatingConfig ? 'Removing...' : 'Remove URL'}
@@ -282,3 +236,5 @@ export const RedirectUrls = () => {
)
}
+
+export default RedirectUrls
diff --git a/apps/studio/components/interfaces/Auth/RedirectUrls/ValueContainer.tsx b/apps/studio/components/interfaces/Auth/RedirectUrls/ValueContainer.tsx
index c0f32b9a9f3..ec36304761c 100644
--- a/apps/studio/components/interfaces/Auth/RedirectUrls/ValueContainer.tsx
+++ b/apps/studio/components/interfaces/Auth/RedirectUrls/ValueContainer.tsx
@@ -1,29 +1,17 @@
-import { PropsWithChildren, MouseEvent } from 'react'
+import { PropsWithChildren } from 'react'
-import { cn } from 'ui'
-
-interface ValueContainerProps {
- isSelected?: boolean
- onClick?: (event: MouseEvent) => void
-}
-
-export const ValueContainer = ({
- children,
- isSelected = false,
- onClick,
-}: PropsWithChildren) => (
+const ValueContainer = ({ children }: PropsWithChildren<{}>) => (
{
- if (onClick) onClick(e)
- }}
+ className="
+ bg-surface-100 border-default text-foreground flex items-center
+ justify-between gap-2
+ border px-6
+ py-4 text-sm
+ first:rounded-tr first:rounded-tl last:rounded-br last:rounded-bl
+ "
>
{children}
)
+
+export default ValueContainer
diff --git a/apps/studio/pages/project/[ref]/auth/url-configuration.tsx b/apps/studio/pages/project/[ref]/auth/url-configuration.tsx
index 36aae336e66..0d59eb7935c 100644
--- a/apps/studio/pages/project/[ref]/auth/url-configuration.tsx
+++ b/apps/studio/pages/project/[ref]/auth/url-configuration.tsx
@@ -1,6 +1,6 @@
import { PermissionAction } from '@supabase/shared-types/out/constants'
-import { RedirectUrls } from 'components/interfaces/Auth/RedirectUrls/RedirectUrls'
+import RedirectUrls from 'components/interfaces/Auth/RedirectUrls/RedirectUrls'
import SiteUrl from 'components/interfaces/Auth/SiteUrl/SiteUrl'
import AuthLayout from 'components/layouts/AuthLayout/AuthLayout'
import { FormsContainer } from 'components/ui/Forms/FormsContainer'