diff --git a/webapp/src/App.tsx b/webapp/src/App.tsx index 6e052ec..4541a71 100644 --- a/webapp/src/App.tsx +++ b/webapp/src/App.tsx @@ -1115,8 +1115,6 @@ export default function App() { queryFn: () => listPendingAuthRequests(authedFetch, profile?.email || session?.email || ''), enabled: !IS_DEMO_MODE && phase === 'app' && !!session?.accessToken && !!session?.symEncKey && !!session?.symMacKey && !!(profile?.email || session?.email), staleTime: 5_000, - refetchInterval: 15_000, - refetchIntervalInBackground: true, }); const pendingAuthRequests = (pendingAuthRequestsQuery.data || []).filter(isPendingAuthRequest); const latestPendingAuthRequest = pendingAuthRequests[0] || null; @@ -2015,7 +2013,8 @@ export default function App() { onEnableAccountPasskeyDirectUnlock: accountSecurityActions.enableAccountPasskeyDirectUnlock, onDeleteAccountPasskey: accountSecurityActions.deleteAccountPasskey, pendingAuthRequests, - pendingAuthRequestsLoading: pendingAuthRequestsQuery.isFetching, + pendingAuthRequestsLoading: pendingAuthRequestsQuery.isLoading, + pendingAuthRequestsRefreshing: pendingAuthRequestsQuery.isFetching && !pendingAuthRequestsQuery.isLoading, onRefreshPendingAuthRequests: async () => { await pendingAuthRequestsQuery.refetch(); }, diff --git a/webapp/src/components/AppMainRoutes.tsx b/webapp/src/components/AppMainRoutes.tsx index 74bbc4f..a4e6db0 100644 --- a/webapp/src/components/AppMainRoutes.tsx +++ b/webapp/src/components/AppMainRoutes.tsx @@ -119,6 +119,7 @@ export interface AppMainRoutesProps { onDeleteAccountPasskey: (id: string, masterPassword: string) => Promise; pendingAuthRequests: AuthRequest[]; pendingAuthRequestsLoading: boolean; + pendingAuthRequestsRefreshing: boolean; onRefreshPendingAuthRequests: () => Promise; onApproveAuthRequest: (request: AuthRequest) => Promise; onDenyAuthRequest: (request: AuthRequest) => Promise; @@ -354,6 +355,7 @@ export default function AppMainRoutes(props: AppMainRoutesProps) { error={props.authorizedDevicesError} pendingAuthRequests={props.pendingAuthRequests} pendingAuthRequestsLoading={props.pendingAuthRequestsLoading} + pendingAuthRequestsRefreshing={props.pendingAuthRequestsRefreshing} onRefresh={() => void props.onRefreshAuthorizedDevices()} onRefreshPendingAuthRequests={props.onRefreshPendingAuthRequests} onApproveAuthRequest={props.onApproveAuthRequest} diff --git a/webapp/src/components/PendingAuthRequestsPanel.tsx b/webapp/src/components/PendingAuthRequestsPanel.tsx index d559651..debd92f 100644 --- a/webapp/src/components/PendingAuthRequestsPanel.tsx +++ b/webapp/src/components/PendingAuthRequestsPanel.tsx @@ -7,6 +7,7 @@ import { t } from '@/lib/i18n'; interface PendingAuthRequestsPanelProps { pendingAuthRequests: AuthRequest[]; pendingAuthRequestsLoading: boolean; + pendingAuthRequestsRefreshing?: boolean; onRefreshPendingAuthRequests: () => Promise; onApproveAuthRequest: (request: AuthRequest) => Promise; onDenyAuthRequest: (request: AuthRequest) => Promise; @@ -22,6 +23,7 @@ function formatDateTime(value: string | null | undefined): string { export default function PendingAuthRequestsPanel(props: PendingAuthRequestsPanelProps) { const [authRequestSubmittingId, setAuthRequestSubmittingId] = useState(null); + const refreshing = props.pendingAuthRequestsLoading || !!props.pendingAuthRequestsRefreshing; async function approveAuthRequest(authRequest: AuthRequest): Promise { if (authRequestSubmittingId) return; @@ -50,10 +52,10 @@ export default function PendingAuthRequestsPanel(props: PendingAuthRequestsPanel diff --git a/webapp/src/components/SecurityDevicesPage.tsx b/webapp/src/components/SecurityDevicesPage.tsx index 583bdc4..380c865 100644 --- a/webapp/src/components/SecurityDevicesPage.tsx +++ b/webapp/src/components/SecurityDevicesPage.tsx @@ -13,6 +13,7 @@ interface SecurityDevicesPageProps { error: string; pendingAuthRequests: AuthRequest[]; pendingAuthRequestsLoading: boolean; + pendingAuthRequestsRefreshing: boolean; onRefresh: () => void; onRefreshPendingAuthRequests: () => Promise; onApproveAuthRequest: (request: AuthRequest) => Promise; @@ -106,6 +107,7 @@ export default function SecurityDevicesPage(props: SecurityDevicesPageProps) { loadingVariant="compact" pendingAuthRequests={props.pendingAuthRequests} pendingAuthRequestsLoading={props.pendingAuthRequestsLoading} + pendingAuthRequestsRefreshing={props.pendingAuthRequestsRefreshing} onRefreshPendingAuthRequests={props.onRefreshPendingAuthRequests} onApproveAuthRequest={props.onApproveAuthRequest} onDenyAuthRequest={props.onDenyAuthRequest} diff --git a/webapp/src/styles/forms.css b/webapp/src/styles/forms.css index fd9b5c4..0409d57 100644 --- a/webapp/src/styles/forms.css +++ b/webapp/src/styles/forms.css @@ -172,6 +172,10 @@ input[type='file'].input::file-selector-button:hover { @apply shrink-0; } +.btn-icon-spin { + animation: spin 0.9s linear infinite; +} + .btn.full { @apply my-2.5 h-12 w-full; font-size: var(--font-md);