mirror of
https://github.com/shuaiplus/nodewarden.git
synced 2026-08-04 22:40:11 +00:00
refactor: consolidate security devices UI and remove pending auth requests from settings
- Merge device management and authorized devices sections into a single card in SecurityDevicesPage - Remove PendingAuthRequestsPanel from SettingsPage and its related props - Clean up unused auth request prop drilling in AppMainRoutes Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -275,11 +275,6 @@ export default function AppMainRoutes(props: AppMainRoutesProps) {
|
|||||||
onCreateAccountPasskey={props.onCreateAccountPasskey}
|
onCreateAccountPasskey={props.onCreateAccountPasskey}
|
||||||
onEnableAccountPasskeyDirectUnlock={props.onEnableAccountPasskeyDirectUnlock}
|
onEnableAccountPasskeyDirectUnlock={props.onEnableAccountPasskeyDirectUnlock}
|
||||||
onDeleteAccountPasskey={props.onDeleteAccountPasskey}
|
onDeleteAccountPasskey={props.onDeleteAccountPasskey}
|
||||||
pendingAuthRequests={props.pendingAuthRequests}
|
|
||||||
pendingAuthRequestsLoading={props.pendingAuthRequestsLoading}
|
|
||||||
onRefreshPendingAuthRequests={props.onRefreshPendingAuthRequests}
|
|
||||||
onApproveAuthRequest={props.onApproveAuthRequest}
|
|
||||||
onDenyAuthRequest={props.onDenyAuthRequest}
|
|
||||||
onLockTimeoutChange={props.onLockTimeoutChange}
|
onLockTimeoutChange={props.onLockTimeoutChange}
|
||||||
onSessionTimeoutActionChange={props.onSessionTimeoutActionChange}
|
onSessionTimeoutActionChange={props.onSessionTimeoutActionChange}
|
||||||
onNotify={props.onNotify}
|
onNotify={props.onNotify}
|
||||||
|
|||||||
@@ -89,42 +89,38 @@ export default function SecurityDevicesPage(props: SecurityDevicesPageProps) {
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<section className="card">
|
<section className="card">
|
||||||
<div className="section-head">
|
<div className="section-head">
|
||||||
<div>
|
<div>
|
||||||
<h3 className="flush-title">{t('txt_device_management')}</h3>
|
<h3 className="flush-title">{t('txt_authorized_devices')}</h3>
|
||||||
<div className="muted-inline section-note">
|
<div className="muted-inline section-note">
|
||||||
{t('txt_manage_device_sessions_and_30_day_totp_trusted_sessions')}
|
{t('txt_manage_device_sessions_and_30_day_totp_trusted_sessions')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="actions">
|
||||||
|
<button type="button" className="btn btn-secondary small" disabled={props.loading} onClick={props.onRefresh}>
|
||||||
|
<RefreshCw size={14} className="btn-icon" />
|
||||||
|
{t('txt_refresh')}
|
||||||
|
</button>
|
||||||
|
<button type="button" className="btn btn-danger small" onClick={props.onRevokeAll}>
|
||||||
|
<ShieldOff size={14} className="btn-icon" />
|
||||||
|
{t('txt_revoke_all_trusted')}
|
||||||
|
</button>
|
||||||
|
<button type="button" className="btn btn-danger small" onClick={props.onRemoveAll}>
|
||||||
|
<Trash2 size={14} className="btn-icon" />
|
||||||
|
{t('txt_remove_all_devices')}
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="actions">
|
{!!props.error && (
|
||||||
<button type="button" className="btn btn-secondary small" disabled={props.loading} onClick={props.onRefresh}>
|
<div className="local-error">
|
||||||
<RefreshCw size={14} className="btn-icon" />
|
<span>{props.error}</span>
|
||||||
{t('txt_refresh')}
|
<button type="button" className="btn btn-secondary small" disabled={props.loading} onClick={props.onRefresh}>
|
||||||
</button>
|
<RefreshCw size={14} className="btn-icon" />
|
||||||
<button type="button" className="btn btn-danger small" onClick={props.onRevokeAll}>
|
{t('txt_refresh')}
|
||||||
<ShieldOff size={14} className="btn-icon" />
|
</button>
|
||||||
{t('txt_revoke_all_trusted')}
|
</div>
|
||||||
</button>
|
)}
|
||||||
<button type="button" className="btn btn-danger small" onClick={props.onRemoveAll}>
|
<table className="table authorized-devices-table">
|
||||||
<Trash2 size={14} className="btn-icon" />
|
|
||||||
{t('txt_remove_all_devices')}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section className="card">
|
|
||||||
<h3 className="section-title-flush">{t('txt_authorized_devices')}</h3>
|
|
||||||
{!!props.error && (
|
|
||||||
<div className="local-error">
|
|
||||||
<span>{props.error}</span>
|
|
||||||
<button type="button" className="btn btn-secondary small" disabled={props.loading} onClick={props.onRefresh}>
|
|
||||||
<RefreshCw size={14} className="btn-icon" />
|
|
||||||
{t('txt_refresh')}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<table className="table authorized-devices-table">
|
|
||||||
<colgroup>
|
<colgroup>
|
||||||
<col className="authorized-devices-col-device" />
|
<col className="authorized-devices-col-device" />
|
||||||
<col className="authorized-devices-col-type" />
|
<col className="authorized-devices-col-type" />
|
||||||
@@ -233,7 +229,7 @@ export default function SecurityDevicesPage(props: SecurityDevicesPageProps) {
|
|||||||
</tr>
|
</tr>
|
||||||
)}
|
)}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -2,10 +2,9 @@ import { useEffect, useMemo, useState } from 'preact/hooks';
|
|||||||
import { Clipboard, KeyRound, RefreshCw, ShieldCheck, ShieldOff, Trash2 } from 'lucide-preact';
|
import { Clipboard, KeyRound, RefreshCw, ShieldCheck, ShieldOff, Trash2 } from 'lucide-preact';
|
||||||
import { copyTextToClipboard } from '@/lib/clipboard';
|
import { copyTextToClipboard } from '@/lib/clipboard';
|
||||||
import qrcode from 'qrcode-generator';
|
import qrcode from 'qrcode-generator';
|
||||||
import type { AccountPasskeyCredential, AuthRequest, Profile } from '@/lib/types';
|
import type { AccountPasskeyCredential, Profile } from '@/lib/types';
|
||||||
import { AVAILABLE_LOCALES, getLocale, setLocale, t, type Locale } from '@/lib/i18n';
|
import { AVAILABLE_LOCALES, getLocale, setLocale, t, type Locale } from '@/lib/i18n';
|
||||||
import ConfirmDialog from '@/components/ConfirmDialog';
|
import ConfirmDialog from '@/components/ConfirmDialog';
|
||||||
import PendingAuthRequestsPanel from '@/components/PendingAuthRequestsPanel';
|
|
||||||
|
|
||||||
interface SettingsPageProps {
|
interface SettingsPageProps {
|
||||||
profile: Profile;
|
profile: Profile;
|
||||||
@@ -23,11 +22,6 @@ interface SettingsPageProps {
|
|||||||
onCreateAccountPasskey: (name: string, masterPassword: string, directUnlock: boolean) => Promise<AccountPasskeyCredential | null>;
|
onCreateAccountPasskey: (name: string, masterPassword: string, directUnlock: boolean) => Promise<AccountPasskeyCredential | null>;
|
||||||
onEnableAccountPasskeyDirectUnlock: (id: string, masterPassword: string) => Promise<void>;
|
onEnableAccountPasskeyDirectUnlock: (id: string, masterPassword: string) => Promise<void>;
|
||||||
onDeleteAccountPasskey: (id: string, masterPassword: string) => Promise<void>;
|
onDeleteAccountPasskey: (id: string, masterPassword: string) => Promise<void>;
|
||||||
pendingAuthRequests: AuthRequest[];
|
|
||||||
pendingAuthRequestsLoading: boolean;
|
|
||||||
onRefreshPendingAuthRequests: () => Promise<void>;
|
|
||||||
onApproveAuthRequest: (request: AuthRequest) => Promise<void>;
|
|
||||||
onDenyAuthRequest: (request: AuthRequest) => Promise<void>;
|
|
||||||
onLockTimeoutChange: (minutes: 0 | 1 | 5 | 15 | 30) => void;
|
onLockTimeoutChange: (minutes: 0 | 1 | 5 | 15 | 30) => void;
|
||||||
onSessionTimeoutActionChange: (action: 'lock' | 'logout') => void;
|
onSessionTimeoutActionChange: (action: 'lock' | 'logout') => void;
|
||||||
onNotify?: (type: 'success' | 'error' | 'warning', text: string) => void;
|
onNotify?: (type: 'success' | 'error' | 'warning', text: string) => void;
|
||||||
@@ -515,15 +509,6 @@ export default function SettingsPage(props: SettingsPageProps) {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<PendingAuthRequestsPanel
|
|
||||||
pendingAuthRequests={props.pendingAuthRequests}
|
|
||||||
pendingAuthRequestsLoading={props.pendingAuthRequestsLoading}
|
|
||||||
onRefreshPendingAuthRequests={props.onRefreshPendingAuthRequests}
|
|
||||||
onApproveAuthRequest={props.onApproveAuthRequest}
|
|
||||||
onDenyAuthRequest={props.onDenyAuthRequest}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<section className="settings-module sensitive-actions-module">
|
<section className="settings-module sensitive-actions-module">
|
||||||
<div className="sensitive-actions-grid">
|
<div className="sensitive-actions-grid">
|
||||||
<div className="sensitive-action">
|
<div className="sensitive-action">
|
||||||
|
|||||||
Reference in New Issue
Block a user