Files
supabase/apps/studio/components/interfaces/Auth/AuthProvidersForm/FormField.tsx
Monica Khoury 3369164f96 Fix: unify Client ID handling for Google provider (#29950)
* Fix: unify Client ID handling for Google provider

* Ensure no spaces in Client IDs

* Update apps/studio/components/interfaces/Auth/AuthProvidersFormValidation.tsx

Co-authored-by: Kang Ming <kang.ming1996@gmail.com>

* Fix Apple provider client IDs

* Update apps/studio/components/interfaces/Auth/AuthProvidersFormValidation.tsx

Co-authored-by: Kang Ming <kang.ming1996@gmail.com>

* Update apps/studio/components/interfaces/Auth/AuthProvidersFormValidation.tsx

Co-authored-by: Kang Ming <kang.ming1996@gmail.com>

* Remove Secret key requirement

* Fix markdown component usage + apple client id

---------

Co-authored-by: Kang Ming <kang.ming1996@gmail.com>
Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
2024-11-11 15:24:46 +08:00

289 lines
8.1 KiB
TypeScript

import dayjs from 'dayjs'
import { Eye, EyeOff } from 'lucide-react'
import { useEffect, useState } from 'react'
import ReactMarkdown from 'react-markdown'
import { Markdown } from 'components/interfaces/Markdown'
import { DatePicker } from 'components/ui/DatePicker'
import { BASE_PATH } from 'lib/constants'
import { Button, Input, InputNumber, Listbox, Toggle } from 'ui'
import type { Enum } from './AuthProvidersForm.types'
interface FormFieldProps {
name: string
properties: any
formValues: any
setFieldValue: (field: string, v: any) => any
disabled?: boolean
}
function formatDate(date: Date): string {
return dayjs(date).format('dddd, MMMM D, YYYY HH:mm:ss Z')
}
const FormField = ({
name,
properties,
formValues,
disabled = false,
setFieldValue,
}: FormFieldProps) => {
const [hidden, setHidden] = useState(!!properties.isSecret)
const [dateAsText, setDateAsText] = useState(
formValues[name] ? formatDate(new Date(formValues[name])) : ''
)
useEffect(() => {
if (properties.show && properties.show.key && !formValues[properties.show.key]) {
setFieldValue(name, '')
setDateAsText('')
}
}, [properties.show && properties.show.key && !formValues[properties.show.key]])
if (properties.show) {
if (properties.show.matches) {
if (!properties.show.matches.includes(formValues[properties.show.key])) {
return null
}
} else if (!formValues[properties.show.key]) {
return null
}
}
switch (properties.type) {
case 'datetime':
return (
<Input
size="small"
layout="vertical"
id={name}
name={name}
type="text"
value={dateAsText}
readOnly
label={properties.title}
labelOptional={
properties.descriptionOptional ? (
<ReactMarkdown unwrapDisallowed disallowedElements={['p']}>
{properties.descriptionOptional}
</ReactMarkdown>
) : null
}
descriptionText={
properties.description ? (
<ReactMarkdown unwrapDisallowed disallowedElements={['p']}>
{properties.description}
</ReactMarkdown>
) : null
}
actions={
<DatePicker
selectsRange={false}
minDate={new Date()}
from={formValues[name]}
to={formValues[name]}
onChange={(date) => {
if (date && date.to) {
setFieldValue(name, date.to)
setDateAsText(formatDate(new Date(date.to)))
} else {
setDateAsText('')
setFieldValue(name, '')
}
}}
>
<span>Pick</span>
</DatePicker>
}
/>
)
case 'string':
return (
<Input
size="small"
layout="vertical"
id={name}
name={name}
disabled={disabled}
type={hidden ? 'password' : 'text'}
label={properties.title}
labelOptional={
properties.descriptionOptional ? (
<Markdown
content={properties.descriptionOptional}
className="text-foreground-lighter"
/>
) : null
}
descriptionText={
properties.description ? (
<Markdown content={properties.description} className="text-foreground-lighter" />
) : null
}
actions={
!!properties.isSecret ? (
<Button
icon={hidden ? <Eye /> : <EyeOff />}
type="default"
onClick={() => setHidden(!hidden)}
/>
) : (
<span className="mr-3 text-foreground-lighter">
{properties.units ? (
<ReactMarkdown unwrapDisallowed disallowedElements={['p']}>
{properties.units}
</ReactMarkdown>
) : null}
</span>
)
}
/>
)
case 'multiline-string':
return (
<Input.TextArea
size="small"
layout="vertical"
id={name}
name={name}
disabled={disabled}
type={hidden ? 'password' : 'text'}
label={properties.title}
labelOptional={
properties.descriptionOptional ? (
<ReactMarkdown unwrapDisallowed disallowedElements={['p']}>
{properties.descriptionOptional}
</ReactMarkdown>
) : undefined
}
descriptionText={
properties.description ? (
<Markdown content={properties.description} className="text-foreground-lighter" />
) : null
}
actions={
!!properties.isSecret ? (
<Button
icon={hidden ? <Eye /> : <EyeOff />}
type="default"
onClick={() => setHidden(!hidden)}
/>
) : (
<span className="mr-3 text-scale-900">
{properties.units ? (
<ReactMarkdown unwrapDisallowed disallowedElements={['p']}>
{properties.units}
</ReactMarkdown>
) : null}
</span>
)
}
/>
)
case 'number':
return (
<InputNumber
size="small"
layout="vertical"
id={name}
name={name}
disabled={disabled}
label={properties.title}
labelOptional={
properties.descriptionOptional ? (
<ReactMarkdown unwrapDisallowed disallowedElements={['p']}>
{properties.descriptionOptional}
</ReactMarkdown>
) : null
}
descriptionText={
properties.description ? (
<Markdown content={properties.description} className="text-foreground-lighter" />
) : null
}
actions={
<span className="mr-3 text-foreground-lighter">
{properties.units ? (
<ReactMarkdown unwrapDisallowed disallowedElements={['p']}>
{properties.units}
</ReactMarkdown>
) : null}
</span>
}
/>
)
case 'boolean':
return (
<Toggle
size="small"
id={name}
name={name}
disabled={disabled}
label={properties.title}
descriptionText={
properties.description ? (
<ReactMarkdown
unwrapDisallowed
disallowedElements={['p']}
className="form-field-markdown"
>
{properties.description}
</ReactMarkdown>
) : null
}
/>
)
case 'select':
return (
<Listbox
size="small"
name={name}
disabled={disabled}
label={properties.title}
descriptionText={
properties.description ? (
<ReactMarkdown
unwrapDisallowed
disallowedElements={['p']}
className="form-field-markdown"
>
{properties.description}
</ReactMarkdown>
) : null
}
defaultValue={properties.enum[0]}
>
{properties.enum.map((option: Enum) => {
return (
<Listbox.Option
id={option.value}
key={option.value}
label={option.label}
value={option.value}
addOnBefore={() => {
return option.icon ? (
<img className="h-6 w-6" src={`${BASE_PATH}/img/icons/${option.icon}`} />
) : null
}}
>
{option.label}
</Listbox.Option>
)
})}
</Listbox>
)
default:
break
}
return <></>
}
export default FormField