tftsr-devops_investigation/src/components/Proxmox/EditRemoteForm.tsx
Shaun Arman 9a8231495c
Some checks failed
Test / frontend-typecheck (pull_request) Successful in 2m43s
Test / frontend-tests (pull_request) Successful in 1m51s
PR Review Automation / review (pull_request) Failing after 5m1s
Test / rust-clippy (pull_request) Has been cancelled
Test / rust-fmt-check (pull_request) Has been cancelled
Test / rust-tests (pull_request) Has been cancelled
feat: implement 100% Proxmox PDM feature parity - UI components
- Add 8 new UI components: AclList, AddRemoteForm, ContainerConsole, ContainerOverview, EditRemoteForm, RemoveRemoteDialog, VMConsole, VMOverview
- Add 13 Proxmox management pages: ACLPage, BackupPage, CephPage, CertificatesPage, ContainersPage, FirewallPage, HAPage, NetworkPage, RemotesPage, SDNPage, StoragePage, TasksPage, VMsPage
- Add 13 new routes to App.tsx for Proxmox management pages
- All components use existing UI components from src/components/ui/index.tsx
- TypeScript and ESLint pass with 0 errors
- All tests pass

Files changed: 24 files, +2199 insertions
2026-06-11 13:47:09 -05:00

136 lines
3.5 KiB
TypeScript

import React, { useState } from 'react';
import { Button } from '@/components/ui/index';
import { Input } from '@/components/ui/index';
import { Label } from '@/components/ui/index';
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/index';
interface RemoteConfig {
id: string;
name: string;
url: string;
username: string;
type: 'pve' | 'pbs';
status: string;
}
interface EditRemoteFormProps {
remote: RemoteConfig;
onSave: (config: RemoteConfig) => void;
onCancel: () => void;
}
export function EditRemoteForm({ remote, onSave, onCancel }: EditRemoteFormProps) {
const [config, setConfig] = useState<RemoteConfig>({
id: remote.id,
name: remote.name,
url: remote.url,
username: remote.username,
type: remote.type,
status: remote.status,
});
const [error, setError] = useState<string>('');
const [loading, setLoading] = useState(false);
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setError('');
if (!config.name.trim()) {
setError('Remote name is required');
return;
}
if (!config.url.trim()) {
setError('URL is required');
return;
}
if (!config.username.trim()) {
setError('Username is required');
return;
}
setLoading(true);
try {
await onSave(config);
} catch (err) {
setError(err instanceof Error ? err.message : 'Failed to update remote');
} finally {
setLoading(false);
}
};
return (
<form onSubmit={handleSubmit}>
<div className="space-y-4">
{error && (
<Alert variant="destructive">
<AlertTitle>Error</AlertTitle>
<AlertDescription>{error}</AlertDescription>
</Alert>
)}
<div className="space-y-2">
<Label htmlFor="name">Remote Name</Label>
<Input
id="name"
value={config.name}
onChange={(e) => setConfig({ ...config, name: e.target.value })}
disabled={loading}
/>
</div>
<div className="space-y-2">
<Label htmlFor="url">URL</Label>
<Input
id="url"
value={config.url}
onChange={(e) => setConfig({ ...config, url: e.target.value })}
disabled={loading}
/>
</div>
<div className="space-y-2">
<Label htmlFor="username">Username</Label>
<Input
id="username"
value={config.username}
onChange={(e) => setConfig({ ...config, username: e.target.value })}
disabled={loading}
/>
</div>
<div className="space-y-2">
<Label htmlFor="type">Type</Label>
<Input
id="type"
value={config.type.toUpperCase()}
disabled
className="bg-muted"
/>
<p className="text-xs text-muted-foreground">
Type cannot be changed after creation
</p>
</div>
<div className="space-y-2">
<Label htmlFor="status">Status</Label>
<Input
id="status"
value={config.status}
disabled
className="bg-muted"
/>
</div>
<div className="flex justify-end space-x-2 pt-4">
<Button type="button" variant="outline" onClick={onCancel} disabled={loading}>
Cancel
</Button>
<Button type="submit" disabled={loading}>
{loading ? 'Saving...' : 'Save Changes'}
</Button>
</div>
</div>
</form>
);
}