fix: persist Proxmox settings via localStorage; fix Remotes add/refresh flow
- ProxmoxSettings: load all six settings from localStorage on mount via useEffect, wire Save button to write values and show a 2s confirmation, wire Reset button to clear keys and restore defaults - RemotesPage: attach loadRemotes() to the header Refresh button onClick and replace the no-op onRefresh prop passed to RemotesList - EditRemoteForm: add password field to RemoteConfig interface and form so handleEditRemote receives a complete config; use DialogFooter for consistent button layout
This commit is contained in:
parent
38eecaafcf
commit
87e21e243e
@ -3,12 +3,14 @@ import { Button } from '@/components/ui/index';
|
|||||||
import { Input } from '@/components/ui/index';
|
import { Input } from '@/components/ui/index';
|
||||||
import { Label } from '@/components/ui/index';
|
import { Label } from '@/components/ui/index';
|
||||||
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/index';
|
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/index';
|
||||||
|
import { DialogFooter } from '@/components/ui/index';
|
||||||
|
|
||||||
interface RemoteConfig {
|
interface RemoteConfig {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
url: string;
|
url: string;
|
||||||
username: string;
|
username: string;
|
||||||
|
password?: string;
|
||||||
type: 'pve' | 'pbs';
|
type: 'pve' | 'pbs';
|
||||||
status: string;
|
status: string;
|
||||||
}
|
}
|
||||||
@ -25,6 +27,7 @@ export function EditRemoteForm({ remote, onSave, onCancel }: EditRemoteFormProps
|
|||||||
name: remote.name,
|
name: remote.name,
|
||||||
url: remote.url,
|
url: remote.url,
|
||||||
username: remote.username,
|
username: remote.username,
|
||||||
|
password: '',
|
||||||
type: remote.type,
|
type: remote.type,
|
||||||
status: remote.status,
|
status: remote.status,
|
||||||
});
|
});
|
||||||
@ -98,6 +101,21 @@ export function EditRemoteForm({ remote, onSave, onCancel }: EditRemoteFormProps
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className="space-y-2">
|
||||||
|
<Label htmlFor="password">Password</Label>
|
||||||
|
<Input
|
||||||
|
id="password"
|
||||||
|
type="password"
|
||||||
|
value={config.password || ''}
|
||||||
|
onChange={(e) => setConfig({ ...config, password: e.target.value })}
|
||||||
|
placeholder="Enter new password (leave blank to keep existing)"
|
||||||
|
disabled={loading}
|
||||||
|
/>
|
||||||
|
<p className="text-xs text-muted-foreground">
|
||||||
|
Leave blank to keep the existing password
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label htmlFor="type">Type</Label>
|
<Label htmlFor="type">Type</Label>
|
||||||
<Input
|
<Input
|
||||||
@ -121,14 +139,14 @@ export function EditRemoteForm({ remote, onSave, onCancel }: EditRemoteFormProps
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex justify-end space-x-2 pt-4">
|
<DialogFooter className="flex justify-end space-x-2 pt-4">
|
||||||
<Button type="button" variant="outline" onClick={onCancel} disabled={loading}>
|
<Button type="button" variant="outline" onClick={onCancel} disabled={loading}>
|
||||||
Cancel
|
Cancel
|
||||||
</Button>
|
</Button>
|
||||||
<Button type="submit" disabled={loading}>
|
<Button type="submit" disabled={loading}>
|
||||||
{loading ? 'Saving...' : 'Save Changes'}
|
{loading ? 'Saving...' : 'Save Changes'}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</DialogFooter>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -117,7 +117,7 @@ export function ProxmoxRemotesPage() {
|
|||||||
<p className="text-muted-foreground">Manage Proxmox VE and Backup Server connections</p>
|
<p className="text-muted-foreground">Manage Proxmox VE and Backup Server connections</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex space-x-2">
|
<div className="flex space-x-2">
|
||||||
<Button variant="outline" size="sm">
|
<Button variant="outline" size="sm" onClick={() => { void loadRemotes(); }}>
|
||||||
<RefreshCw className="mr-2 h-4 w-4" />
|
<RefreshCw className="mr-2 h-4 w-4" />
|
||||||
Refresh
|
Refresh
|
||||||
</Button>
|
</Button>
|
||||||
@ -130,7 +130,7 @@ export function ProxmoxRemotesPage() {
|
|||||||
|
|
||||||
<RemotesList
|
<RemotesList
|
||||||
remotes={remotes}
|
remotes={remotes}
|
||||||
onRefresh={() => {}}
|
onRefresh={() => { void loadRemotes(); }}
|
||||||
onEdit={(remote) => {
|
onEdit={(remote) => {
|
||||||
setEditingRemote(remote as RemoteInfo | null);
|
setEditingRemote(remote as RemoteInfo | null);
|
||||||
}}
|
}}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import React from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/index';
|
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/index';
|
||||||
import { Label } from '@/components/ui/index';
|
import { Label } from '@/components/ui/index';
|
||||||
import { Switch } from '@/components/ui/index';
|
import { Switch } from '@/components/ui/index';
|
||||||
@ -6,12 +6,22 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@
|
|||||||
import { Button } from '@/components/ui/index';
|
import { Button } from '@/components/ui/index';
|
||||||
|
|
||||||
export function ProxmoxSettings() {
|
export function ProxmoxSettings() {
|
||||||
const [defaultPort, setDefaultPort] = React.useState<string>('8006');
|
const [defaultPort, setDefaultPort] = useState<string>('8006');
|
||||||
const [connectionTimeout, setConnectionTimeout] = React.useState<string>('30');
|
const [connectionTimeout, setConnectionTimeout] = useState<string>('30');
|
||||||
const [retryAttempts, setRetryAttempts] = React.useState<string>('3');
|
const [retryAttempts, setRetryAttempts] = useState<string>('3');
|
||||||
const [verifyCertificates, setVerifyCertificates] = React.useState(true);
|
const [verifyCertificates, setVerifyCertificates] = useState(true);
|
||||||
const [enableCaching, setEnableCaching] = React.useState(true);
|
const [enableCaching, setEnableCaching] = useState(true);
|
||||||
const [enableDebug, setEnableDebug] = React.useState(false);
|
const [enableDebug, setEnableDebug] = useState(false);
|
||||||
|
const [saved, setSaved] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setDefaultPort(localStorage.getItem('proxmox_default_port') ?? '8006');
|
||||||
|
setConnectionTimeout(localStorage.getItem('proxmox_connection_timeout') ?? '30');
|
||||||
|
setRetryAttempts(localStorage.getItem('proxmox_retry_attempts') ?? '3');
|
||||||
|
setVerifyCertificates((localStorage.getItem('proxmox_verify_certificates') ?? 'true') === 'true');
|
||||||
|
setEnableCaching((localStorage.getItem('proxmox_enable_caching') ?? 'true') === 'true');
|
||||||
|
setEnableDebug((localStorage.getItem('proxmox_enable_debug') ?? 'false') === 'true');
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
@ -114,9 +124,40 @@ export function ProxmoxSettings() {
|
|||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
<div className="flex justify-end space-x-2 pt-4">
|
<div className="flex items-center justify-end space-x-2 pt-4">
|
||||||
<Button variant="outline">Reset to Defaults</Button>
|
<Button
|
||||||
<Button>Save Settings</Button>
|
variant="outline"
|
||||||
|
onClick={() => {
|
||||||
|
['proxmox_default_port', 'proxmox_connection_timeout', 'proxmox_retry_attempts',
|
||||||
|
'proxmox_verify_certificates', 'proxmox_enable_caching', 'proxmox_enable_debug']
|
||||||
|
.forEach((k) => localStorage.removeItem(k));
|
||||||
|
setDefaultPort('8006');
|
||||||
|
setConnectionTimeout('30');
|
||||||
|
setRetryAttempts('3');
|
||||||
|
setVerifyCertificates(true);
|
||||||
|
setEnableCaching(true);
|
||||||
|
setEnableDebug(false);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Reset to Defaults
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
onClick={() => {
|
||||||
|
localStorage.setItem('proxmox_default_port', defaultPort);
|
||||||
|
localStorage.setItem('proxmox_connection_timeout', connectionTimeout);
|
||||||
|
localStorage.setItem('proxmox_retry_attempts', retryAttempts);
|
||||||
|
localStorage.setItem('proxmox_verify_certificates', String(verifyCertificates));
|
||||||
|
localStorage.setItem('proxmox_enable_caching', String(enableCaching));
|
||||||
|
localStorage.setItem('proxmox_enable_debug', String(enableDebug));
|
||||||
|
setSaved(true);
|
||||||
|
setTimeout(() => setSaved(false), 2000);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Save Settings
|
||||||
|
</Button>
|
||||||
|
{saved && (
|
||||||
|
<span className="text-sm text-green-600">Settings saved</span>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user