mirror of
https://github.com/tale/headplane.git
synced 2026-08-27 15:37:04 +00:00
feat: support children in confirmation modal
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
import { Dialog, Transition } from '@headlessui/react'
|
import { Dialog, Transition } from '@headlessui/react'
|
||||||
import { XMarkIcon } from '@heroicons/react/24/outline'
|
import { XMarkIcon } from '@heroicons/react/24/outline'
|
||||||
import clsx from 'clsx'
|
import clsx from 'clsx'
|
||||||
import { Fragment, type SetStateAction, useState } from 'react'
|
import { Fragment, type ReactNode, type SetStateAction, useState } from 'react'
|
||||||
|
|
||||||
import Button from './Button'
|
import Button from './Button'
|
||||||
|
|
||||||
@@ -10,6 +10,7 @@ type HookParameters = {
|
|||||||
description?: string;
|
description?: string;
|
||||||
buttonText?: string;
|
buttonText?: string;
|
||||||
variant?: 'danger' | 'confirm';
|
variant?: 'danger' | 'confirm';
|
||||||
|
children?: ReactNode;
|
||||||
|
|
||||||
// Optional because the button submits
|
// Optional because the button submits
|
||||||
onConfirm?: () => void | Promise<void>;
|
onConfirm?: () => void | Promise<void>;
|
||||||
@@ -100,11 +101,17 @@ function Modal({ parameters, isOpen, setIsOpen }: Properties) {
|
|||||||
{parameters.description}
|
{parameters.description}
|
||||||
</Dialog.Description>
|
</Dialog.Description>
|
||||||
) : undefined}
|
) : undefined}
|
||||||
|
{parameters.children ? (
|
||||||
|
<div className='mt-12 w-full'>
|
||||||
|
{parameters.children}
|
||||||
|
</div>
|
||||||
|
) : undefined}
|
||||||
<Button
|
<Button
|
||||||
variant='emphasized'
|
variant='emphasized'
|
||||||
type='submit'
|
type='submit'
|
||||||
className={clsx(
|
className={clsx(
|
||||||
'w-full mt-12',
|
'w-full',
|
||||||
|
parameters.children ? 'mt-4' : 'mt-12',
|
||||||
parameters.variant === 'danger'
|
parameters.variant === 'danger'
|
||||||
? 'bg-red-800 dark:bg-red-500 focus:ring-red-500 dark:focus:ring-red-500'
|
? 'bg-red-800 dark:bg-red-500 focus:ring-red-500 dark:focus:ring-red-500'
|
||||||
: ''
|
: ''
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { useState } from 'react'
|
|||||||
import Button from '~/components/Button'
|
import Button from '~/components/Button'
|
||||||
import Code from '~/components/Code'
|
import Code from '~/components/Code'
|
||||||
import Input from '~/components/Input'
|
import Input from '~/components/Input'
|
||||||
|
import useModal from '~/components/Modal'
|
||||||
import Spinner from '~/components/Spinner'
|
import Spinner from '~/components/Spinner'
|
||||||
|
|
||||||
type Properties = {
|
type Properties = {
|
||||||
@@ -16,9 +17,31 @@ type Properties = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function Modal({ name, disabled }: Properties) {
|
export default function Modal({ name, disabled }: Properties) {
|
||||||
const [isOpen, setIsOpen] = useState(false)
|
|
||||||
const [newName, setNewName] = useState(name)
|
const [newName, setNewName] = useState(name)
|
||||||
const fetcher = useFetcher()
|
const fetcher = useFetcher()
|
||||||
|
const { Modal, open } = useModal({
|
||||||
|
title: 'Rename Tailnet',
|
||||||
|
description: 'Keep in mind that changing this can lead to all sorts of unexpected behavior and may break existing devices in your tailnet.',
|
||||||
|
buttonText: 'Rename',
|
||||||
|
children: (
|
||||||
|
<Input
|
||||||
|
type='text'
|
||||||
|
className='font-mono mt-4'
|
||||||
|
value={newName}
|
||||||
|
onChange={event => {
|
||||||
|
setNewName(event.target.value)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
onConfirm: () => {
|
||||||
|
fetcher.submit({
|
||||||
|
'dns_config.base_domain': newName
|
||||||
|
}, {
|
||||||
|
method: 'PATCH',
|
||||||
|
encType: 'application/json'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='flex flex-col w-2/3'>
|
<div className='flex flex-col w-2/3'>
|
||||||
@@ -47,7 +70,7 @@ export default function Modal({ name, disabled }: Properties) {
|
|||||||
className='text-sm w-fit'
|
className='text-sm w-fit'
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setIsOpen(true)
|
open()
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{fetcher.state === 'idle' ? undefined : (
|
{fetcher.state === 'idle' ? undefined : (
|
||||||
@@ -55,50 +78,7 @@ export default function Modal({ name, disabled }: Properties) {
|
|||||||
)}
|
)}
|
||||||
Rename Tailnet...
|
Rename Tailnet...
|
||||||
</Button>
|
</Button>
|
||||||
<Dialog
|
{Modal}
|
||||||
className='relative z-50'
|
|
||||||
open={isOpen} onClose={() => {
|
|
||||||
setIsOpen(false)
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div className='fixed inset-0 bg-black/30' aria-hidden='true'/>
|
|
||||||
<div className='fixed inset-0 flex w-screen items-center justify-center'>
|
|
||||||
<Dialog.Panel className='bg-white rounded-lg p-4 w-full max-w-md dark:bg-zinc-800'>
|
|
||||||
<Dialog.Title className='text-lg font-bold'>
|
|
||||||
Rename {name}
|
|
||||||
</Dialog.Title>
|
|
||||||
<Dialog.Description className='text-gray-500 dark:text-gray-400'>
|
|
||||||
Keep in mind that changing this can lead to all sorts
|
|
||||||
of unexpected behavior and may break existing devices
|
|
||||||
in your tailnet.
|
|
||||||
</Dialog.Description>
|
|
||||||
<Input
|
|
||||||
type='text'
|
|
||||||
className='font-mono mt-4'
|
|
||||||
value={newName}
|
|
||||||
onChange={event => {
|
|
||||||
setNewName(event.target.value)
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<button
|
|
||||||
type='submit'
|
|
||||||
className='rounded-lg py-2 bg-gray-800 text-white w-full mt-2'
|
|
||||||
onClick={() => {
|
|
||||||
fetcher.submit({
|
|
||||||
'dns_config.base_domain': newName
|
|
||||||
}, {
|
|
||||||
method: 'PATCH',
|
|
||||||
encType: 'application/json'
|
|
||||||
})
|
|
||||||
|
|
||||||
setIsOpen(false)
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Rename
|
|
||||||
</button>
|
|
||||||
</Dialog.Panel>
|
|
||||||
</div>
|
|
||||||
</Dialog>
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user