mirror of
https://github.com/shuaiplus/nodewarden.git
synced 2026-08-04 22:40:11 +00:00
feat: add pendingAuthRequestsRefreshing state to improve loading feedback in auth request components
This commit is contained in:
+2
-3
@@ -1115,8 +1115,6 @@ export default function App() {
|
|||||||
queryFn: () => listPendingAuthRequests(authedFetch, profile?.email || session?.email || ''),
|
queryFn: () => listPendingAuthRequests(authedFetch, profile?.email || session?.email || ''),
|
||||||
enabled: !IS_DEMO_MODE && phase === 'app' && !!session?.accessToken && !!session?.symEncKey && !!session?.symMacKey && !!(profile?.email || session?.email),
|
enabled: !IS_DEMO_MODE && phase === 'app' && !!session?.accessToken && !!session?.symEncKey && !!session?.symMacKey && !!(profile?.email || session?.email),
|
||||||
staleTime: 5_000,
|
staleTime: 5_000,
|
||||||
refetchInterval: 15_000,
|
|
||||||
refetchIntervalInBackground: true,
|
|
||||||
});
|
});
|
||||||
const pendingAuthRequests = (pendingAuthRequestsQuery.data || []).filter(isPendingAuthRequest);
|
const pendingAuthRequests = (pendingAuthRequestsQuery.data || []).filter(isPendingAuthRequest);
|
||||||
const latestPendingAuthRequest = pendingAuthRequests[0] || null;
|
const latestPendingAuthRequest = pendingAuthRequests[0] || null;
|
||||||
@@ -2015,7 +2013,8 @@ export default function App() {
|
|||||||
onEnableAccountPasskeyDirectUnlock: accountSecurityActions.enableAccountPasskeyDirectUnlock,
|
onEnableAccountPasskeyDirectUnlock: accountSecurityActions.enableAccountPasskeyDirectUnlock,
|
||||||
onDeleteAccountPasskey: accountSecurityActions.deleteAccountPasskey,
|
onDeleteAccountPasskey: accountSecurityActions.deleteAccountPasskey,
|
||||||
pendingAuthRequests,
|
pendingAuthRequests,
|
||||||
pendingAuthRequestsLoading: pendingAuthRequestsQuery.isFetching,
|
pendingAuthRequestsLoading: pendingAuthRequestsQuery.isLoading,
|
||||||
|
pendingAuthRequestsRefreshing: pendingAuthRequestsQuery.isFetching && !pendingAuthRequestsQuery.isLoading,
|
||||||
onRefreshPendingAuthRequests: async () => {
|
onRefreshPendingAuthRequests: async () => {
|
||||||
await pendingAuthRequestsQuery.refetch();
|
await pendingAuthRequestsQuery.refetch();
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -119,6 +119,7 @@ export interface AppMainRoutesProps {
|
|||||||
onDeleteAccountPasskey: (id: string, masterPassword: string) => Promise<void>;
|
onDeleteAccountPasskey: (id: string, masterPassword: string) => Promise<void>;
|
||||||
pendingAuthRequests: AuthRequest[];
|
pendingAuthRequests: AuthRequest[];
|
||||||
pendingAuthRequestsLoading: boolean;
|
pendingAuthRequestsLoading: boolean;
|
||||||
|
pendingAuthRequestsRefreshing: boolean;
|
||||||
onRefreshPendingAuthRequests: () => Promise<void>;
|
onRefreshPendingAuthRequests: () => Promise<void>;
|
||||||
onApproveAuthRequest: (request: AuthRequest) => Promise<void>;
|
onApproveAuthRequest: (request: AuthRequest) => Promise<void>;
|
||||||
onDenyAuthRequest: (request: AuthRequest) => Promise<void>;
|
onDenyAuthRequest: (request: AuthRequest) => Promise<void>;
|
||||||
@@ -354,6 +355,7 @@ export default function AppMainRoutes(props: AppMainRoutesProps) {
|
|||||||
error={props.authorizedDevicesError}
|
error={props.authorizedDevicesError}
|
||||||
pendingAuthRequests={props.pendingAuthRequests}
|
pendingAuthRequests={props.pendingAuthRequests}
|
||||||
pendingAuthRequestsLoading={props.pendingAuthRequestsLoading}
|
pendingAuthRequestsLoading={props.pendingAuthRequestsLoading}
|
||||||
|
pendingAuthRequestsRefreshing={props.pendingAuthRequestsRefreshing}
|
||||||
onRefresh={() => void props.onRefreshAuthorizedDevices()}
|
onRefresh={() => void props.onRefreshAuthorizedDevices()}
|
||||||
onRefreshPendingAuthRequests={props.onRefreshPendingAuthRequests}
|
onRefreshPendingAuthRequests={props.onRefreshPendingAuthRequests}
|
||||||
onApproveAuthRequest={props.onApproveAuthRequest}
|
onApproveAuthRequest={props.onApproveAuthRequest}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { t } from '@/lib/i18n';
|
|||||||
interface PendingAuthRequestsPanelProps {
|
interface PendingAuthRequestsPanelProps {
|
||||||
pendingAuthRequests: AuthRequest[];
|
pendingAuthRequests: AuthRequest[];
|
||||||
pendingAuthRequestsLoading: boolean;
|
pendingAuthRequestsLoading: boolean;
|
||||||
|
pendingAuthRequestsRefreshing?: boolean;
|
||||||
onRefreshPendingAuthRequests: () => Promise<void>;
|
onRefreshPendingAuthRequests: () => Promise<void>;
|
||||||
onApproveAuthRequest: (request: AuthRequest) => Promise<void>;
|
onApproveAuthRequest: (request: AuthRequest) => Promise<void>;
|
||||||
onDenyAuthRequest: (request: AuthRequest) => Promise<void>;
|
onDenyAuthRequest: (request: AuthRequest) => Promise<void>;
|
||||||
@@ -22,6 +23,7 @@ function formatDateTime(value: string | null | undefined): string {
|
|||||||
|
|
||||||
export default function PendingAuthRequestsPanel(props: PendingAuthRequestsPanelProps) {
|
export default function PendingAuthRequestsPanel(props: PendingAuthRequestsPanelProps) {
|
||||||
const [authRequestSubmittingId, setAuthRequestSubmittingId] = useState<string | null>(null);
|
const [authRequestSubmittingId, setAuthRequestSubmittingId] = useState<string | null>(null);
|
||||||
|
const refreshing = props.pendingAuthRequestsLoading || !!props.pendingAuthRequestsRefreshing;
|
||||||
|
|
||||||
async function approveAuthRequest(authRequest: AuthRequest): Promise<void> {
|
async function approveAuthRequest(authRequest: AuthRequest): Promise<void> {
|
||||||
if (authRequestSubmittingId) return;
|
if (authRequestSubmittingId) return;
|
||||||
@@ -50,10 +52,10 @@ export default function PendingAuthRequestsPanel(props: PendingAuthRequestsPanel
|
|||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="btn btn-secondary small"
|
className="btn btn-secondary small"
|
||||||
disabled={props.pendingAuthRequestsLoading}
|
disabled={refreshing}
|
||||||
onClick={() => void props.onRefreshPendingAuthRequests()}
|
onClick={() => void props.onRefreshPendingAuthRequests()}
|
||||||
>
|
>
|
||||||
<RefreshCw size={14} className="btn-icon" />
|
<RefreshCw size={14} className={`btn-icon${refreshing ? ' btn-icon-spin' : ''}`} />
|
||||||
{t('txt_refresh')}
|
{t('txt_refresh')}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ interface SecurityDevicesPageProps {
|
|||||||
error: string;
|
error: string;
|
||||||
pendingAuthRequests: AuthRequest[];
|
pendingAuthRequests: AuthRequest[];
|
||||||
pendingAuthRequestsLoading: boolean;
|
pendingAuthRequestsLoading: boolean;
|
||||||
|
pendingAuthRequestsRefreshing: boolean;
|
||||||
onRefresh: () => void;
|
onRefresh: () => void;
|
||||||
onRefreshPendingAuthRequests: () => Promise<void>;
|
onRefreshPendingAuthRequests: () => Promise<void>;
|
||||||
onApproveAuthRequest: (request: AuthRequest) => Promise<void>;
|
onApproveAuthRequest: (request: AuthRequest) => Promise<void>;
|
||||||
@@ -106,6 +107,7 @@ export default function SecurityDevicesPage(props: SecurityDevicesPageProps) {
|
|||||||
loadingVariant="compact"
|
loadingVariant="compact"
|
||||||
pendingAuthRequests={props.pendingAuthRequests}
|
pendingAuthRequests={props.pendingAuthRequests}
|
||||||
pendingAuthRequestsLoading={props.pendingAuthRequestsLoading}
|
pendingAuthRequestsLoading={props.pendingAuthRequestsLoading}
|
||||||
|
pendingAuthRequestsRefreshing={props.pendingAuthRequestsRefreshing}
|
||||||
onRefreshPendingAuthRequests={props.onRefreshPendingAuthRequests}
|
onRefreshPendingAuthRequests={props.onRefreshPendingAuthRequests}
|
||||||
onApproveAuthRequest={props.onApproveAuthRequest}
|
onApproveAuthRequest={props.onApproveAuthRequest}
|
||||||
onDenyAuthRequest={props.onDenyAuthRequest}
|
onDenyAuthRequest={props.onDenyAuthRequest}
|
||||||
|
|||||||
@@ -172,6 +172,10 @@ input[type='file'].input::file-selector-button:hover {
|
|||||||
@apply shrink-0;
|
@apply shrink-0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.btn-icon-spin {
|
||||||
|
animation: spin 0.9s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
.btn.full {
|
.btn.full {
|
||||||
@apply my-2.5 h-12 w-full;
|
@apply my-2.5 h-12 w-full;
|
||||||
font-size: var(--font-md);
|
font-size: var(--font-md);
|
||||||
|
|||||||
Reference in New Issue
Block a user