headplane/app/routes/machines/dialogs/rename.tsx

92 lines
2.6 KiB
TypeScript
Raw Normal View History

import { useState } from 'react';
2024-12-31 10:30:14 +05:30
import Code from '~/components/Code';
import Dialog from '~/components/Dialog';
2025-01-28 16:02:47 -05:00
import Input from '~/components/Input';
2024-12-31 10:31:50 +05:30
import type { Machine } from '~/types';
interface RenameProps {
machine: Machine;
isOpen: boolean;
magic?: string;
setIsOpen: (isOpen: boolean) => void;
}
export default function Rename({
machine,
magic,
isOpen,
setIsOpen,
}: RenameProps) {
2024-12-31 10:30:14 +05:30
const [name, setName] = useState(machine.givenName);
return (
<Dialog isOpen={isOpen} onOpenChange={setIsOpen}>
<Dialog.Panel>
<Dialog.Title>Edit machine name for {machine.givenName}</Dialog.Title>
2025-02-04 17:21:03 -05:00
<Dialog.Text className="mb-6">
This name is shown in the admin panel, in Tailscale clients, and used
when generating MagicDNS names.
</Dialog.Text>
<input type="hidden" name="action_id" value="rename" />
<input type="hidden" name="node_id" value={machine.id} />
2025-01-28 16:02:47 -05:00
<Input
2025-04-22 09:51:03 -04:00
isRequired
label="Machine name"
placeholder="Machine name"
2025-04-22 09:51:03 -04:00
validationBehavior="native"
name="name"
defaultValue={machine.givenName}
onChange={setName}
2025-04-22 09:51:03 -04:00
validate={(value) => {
if (value.length === 0) {
return 'Cannot be empty';
}
// DNS hostname validation
if (value.toLowerCase() !== value) {
return 'Cannot contain uppercase letters';
}
if (value.length > 63) {
return 'DNS hostnames cannot be 64+ characters';
}
// Test for invalid characters
if (!/^[a-z0-9-]+$/.test(value)) {
return 'Cannot contain special characters';
}
// Test for leading/trailing hyphens
if (value.startsWith('-') || value.endsWith('-')) {
return 'Cannot start or end with a hyphen';
}
// Test for consecutive hyphens
if (value.includes('--')) {
return 'Cannot contain consecutive hyphens';
}
}}
/>
{magic ? (
name.length > 0 && name !== machine.givenName ? (
2025-02-04 17:21:03 -05:00
<p className="text-sm text-headplane-600 dark:text-headplane-300 leading-tight mt-2">
This machine will be accessible by the hostname{' '}
<Code className="text-sm">
{name.toLowerCase().replaceAll(/\s+/g, '-')}
</Code>
{'. '}
The hostname <Code className="text-sm">{machine.givenName}</Code>{' '}
will no longer point to this machine.
</p>
) : (
2025-02-04 17:21:03 -05:00
<p className="text-sm text-headplane-600 dark:text-headplane-300 leading-tight mt-2">
This machine is accessible by the hostname{' '}
<Code className="text-sm">{machine.givenName}</Code>.
</p>
)
) : undefined}
</Dialog.Panel>
</Dialog>
2024-12-31 10:30:14 +05:30
);
}