chore: switch to react-router v7

This commit is contained in:
Aarnav Tale 2024-12-31 10:30:14 +05:30
parent 39504e2487
commit aa9872a45b
No known key found for this signature in database
101 changed files with 3825 additions and 6796 deletions

View file

@ -1,88 +1,88 @@
/* eslint-disable unicorn/no-keyword-prefix */
import {
closestCorners,
DndContext,
DragOverlay
} from '@dnd-kit/core'
import { closestCorners, DndContext, DragOverlay } from '@dnd-kit/core';
import {
restrictToParentElement,
restrictToVerticalAxis
} from '@dnd-kit/modifiers'
restrictToVerticalAxis,
} from '@dnd-kit/modifiers';
import {
arrayMove,
SortableContext,
useSortable,
verticalListSortingStrategy
} from '@dnd-kit/sortable'
import { CSS } from '@dnd-kit/utilities'
import { LockIcon, ThreeBarsIcon } from '@primer/octicons-react'
import { FetcherWithComponents, useFetcher } from '@remix-run/react'
import { useEffect, useState } from 'react'
import { Button, Input } from 'react-aria-components'
verticalListSortingStrategy,
} from '@dnd-kit/sortable';
import { CSS } from '@dnd-kit/utilities';
import { LockIcon, ThreeBarsIcon } from '@primer/octicons-react';
import { FetcherWithComponents, useFetcher } from 'react-router';
import { useEffect, useState } from 'react';
import { Button, Input } from 'react-aria-components';
import Spinner from '~/components/Spinner'
import TableList from '~/components/TableList'
import { cn } from '~/utils/cn'
import Spinner from '~/components/Spinner';
import TableList from '~/components/TableList';
import { cn } from '~/utils/cn';
type Properties = {
readonly baseDomain?: string;
readonly searchDomains: string[];
// eslint-disable-next-line react/boolean-prop-naming
readonly disabled?: boolean;
}
};
export default function Domains({ baseDomain, searchDomains, disabled }: Properties) {
export default function Domains({
baseDomain,
searchDomains,
disabled,
}: Properties) {
// eslint-disable-next-line unicorn/no-null, @typescript-eslint/ban-types
const [activeId, setActiveId] = useState<number | string | null>(null)
const [localDomains, setLocalDomains] = useState(searchDomains)
const [newDomain, setNewDomain] = useState('')
const fetcher = useFetcher()
const [activeId, setActiveId] = useState<number | string | null>(null);
const [localDomains, setLocalDomains] = useState(searchDomains);
const [newDomain, setNewDomain] = useState('');
const fetcher = useFetcher();
useEffect(() => {
setLocalDomains(searchDomains)
}, [searchDomains])
setLocalDomains(searchDomains);
}, [searchDomains]);
return (
<div className='flex flex-col w-2/3'>
<h1 className='text-2xl font-medium mb-4'>Search Domains</h1>
<p className='text-gray-700 dark:text-gray-300 mb-2'>
Set custom DNS search domains for your Tailnet.
When using Magic DNS, your tailnet domain is used as the first search domain.
<div className="flex flex-col w-2/3">
<h1 className="text-2xl font-medium mb-4">Search Domains</h1>
<p className="text-gray-700 dark:text-gray-300 mb-2">
Set custom DNS search domains for your Tailnet. When using Magic DNS,
your tailnet domain is used as the first search domain.
</p>
<DndContext
modifiers={[restrictToVerticalAxis, restrictToParentElement]}
collisionDetection={closestCorners}
onDragStart={event => {
setActiveId(event.active.id)
onDragStart={(event) => {
setActiveId(event.active.id);
}}
onDragEnd={event => {
onDragEnd={(event) => {
// eslint-disable-next-line unicorn/no-null
setActiveId(null)
const { active, over } = event
setActiveId(null);
const { active, over } = event;
if (!over) {
return
return;
}
const activeItem = localDomains[active.id as number - 1]
const overItem = localDomains[over.id as number - 1]
const activeItem = localDomains[(active.id as number) - 1];
const overItem = localDomains[(over.id as number) - 1];
if (!activeItem || !overItem) {
return
return;
}
const oldIndex = localDomains.indexOf(activeItem)
const newIndex = localDomains.indexOf(overItem)
const oldIndex = localDomains.indexOf(activeItem);
const newIndex = localDomains.indexOf(overItem);
if (oldIndex !== newIndex) {
setLocalDomains(arrayMove(localDomains, oldIndex, newIndex))
setLocalDomains(arrayMove(localDomains, oldIndex, newIndex));
}
}}
>
<TableList>
{baseDomain ? (
<TableList.Item key='magic-dns-sd'>
<p className='font-mono text-sm'>{baseDomain}</p>
<LockIcon className='h-4 w-4'/>
<TableList.Item key="magic-dns-sd">
<p className="font-mono text-sm">{baseDomain}</p>
<LockIcon className="h-4 w-4" />
</TableList.Item>
) : undefined}
<SortableContext
@ -101,25 +101,27 @@ export default function Domains({ baseDomain, searchDomains, disabled }: Propert
/>
))}
<DragOverlay adjustScale>
{activeId ? <Domain
isDrag
domain={localDomains[activeId as number - 1]}
localDomains={localDomains}
id={activeId as number - 1}
disabled={disabled}
fetcher={fetcher}
/> : undefined}
{activeId ? (
<Domain
isDrag
domain={localDomains[(activeId as number) - 1]}
localDomains={localDomains}
id={(activeId as number) - 1}
disabled={disabled}
fetcher={fetcher}
/>
) : undefined}
</DragOverlay>
</SortableContext>
{disabled ? undefined : (
<TableList.Item key='add-sd'>
<TableList.Item key="add-sd">
<Input
type='text'
className='font-mono text-sm bg-transparent w-full mr-2'
placeholder='Search Domain'
type="text"
className="font-mono text-sm bg-transparent w-full mr-2"
placeholder="Search Domain"
value={newDomain}
onChange={event => {
setNewDomain(event.target.value)
onChange={(event) => {
setNewDomain(event.target.value);
}}
/>
{fetcher.state === 'idle' ? (
@ -128,32 +130,35 @@ export default function Domains({ baseDomain, searchDomains, disabled }: Propert
'text-sm font-semibold',
'text-blue-600 dark:text-blue-400',
'hover:text-blue-700 dark:hover:text-blue-300',
newDomain.length === 0 && 'opacity-50 cursor-not-allowed'
newDomain.length === 0 && 'opacity-50 cursor-not-allowed',
)}
isDisabled={newDomain.length === 0}
onPress={() => {
fetcher.submit({
// eslint-disable-next-line @typescript-eslint/naming-convention
'dns.search_domains': [...localDomains, newDomain]
}, {
method: 'PATCH',
encType: 'application/json'
})
fetcher.submit(
{
// eslint-disable-next-line @typescript-eslint/naming-convention
'dns.search_domains': [...localDomains, newDomain],
},
{
method: 'PATCH',
encType: 'application/json',
},
);
setNewDomain('')
setNewDomain('');
}}
>
Add
</Button>
) : (
<Spinner className='w-3 h-3 mr-0'/>
<Spinner className="w-3 h-3 mr-0" />
)}
</TableList.Item>
)}
</TableList>
</DndContext>
</div>
)
);
}
type DomainProperties = {
@ -164,17 +169,24 @@ type DomainProperties = {
// eslint-disable-next-line react/boolean-prop-naming
readonly disabled?: boolean;
readonly fetcher: FetcherWithComponents<unknown>;
}
};
function Domain({ domain, id, localDomains, isDrag, disabled, fetcher }: DomainProperties) {
function Domain({
domain,
id,
localDomains,
isDrag,
disabled,
fetcher,
}: DomainProperties) {
const {
attributes,
listeners,
setNodeRef,
transform,
transition,
isDragging
} = useSortable({ id })
isDragging,
} = useSortable({ id });
// TODO: Figure out why TableList.Item breaks dndkit
return (
@ -184,17 +196,19 @@ function Domain({ domain, id, localDomains, isDrag, disabled, fetcher }: DomainP
'flex items-center justify-between px-3 py-2',
'border-b border-gray-200 last:border-b-0 dark:border-zinc-800',
isDragging ? 'text-gray-400' : '',
isDrag ? 'outline outline-1 outline-gray-500 bg-gray-200 dark:bg-zinc-800' : ''
isDrag
? 'outline outline-1 outline-gray-500 bg-gray-200 dark:bg-zinc-800'
: '',
)}
style={{
transform: CSS.Transform.toString(transform),
transition
transition,
}}
>
<p className='font-mono text-sm flex items-center gap-4'>
<p className="font-mono text-sm flex items-center gap-4">
{disabled ? undefined : (
<ThreeBarsIcon
className='h-4 w-4 text-gray-400 focus:outline-none'
className="h-4 w-4 text-gray-400 focus:outline-none"
{...attributes}
{...listeners}
/>
@ -207,21 +221,26 @@ function Domain({ domain, id, localDomains, isDrag, disabled, fetcher }: DomainP
'text-sm',
'text-red-600 dark:text-red-400',
'hover:text-red-700 dark:hover:text-red-300',
disabled && 'opacity-50 cursor-not-allowed'
disabled && 'opacity-50 cursor-not-allowed',
)}
isDisabled={disabled}
onPress={() => {
fetcher.submit({
'dns.search_domains': localDomains.filter((_, index) => index !== id - 1)
}, {
method: 'PATCH',
encType: 'application/json'
})
fetcher.submit(
{
'dns.search_domains': localDomains.filter(
(_, index) => index !== id - 1,
),
},
{
method: 'PATCH',
encType: 'application/json',
},
);
}}
>
Remove
</Button>
)}
</div>
)
);
}