Fix API token generation UX

This commit is contained in:
rcourtman 2025-10-15 22:38:50 +00:00
parent 1d580c658d
commit e2a0fbe816
2 changed files with 53 additions and 51 deletions

View file

@ -11,6 +11,7 @@ import type { DockerHost } from '@/types/api';
interface APITokenManagerProps { interface APITokenManagerProps {
currentTokenHint?: string; currentTokenHint?: string;
onTokensChanged?: () => void; onTokensChanged?: () => void;
refreshing?: boolean;
} }
export const APITokenManager: Component<APITokenManagerProps> = (props) => { export const APITokenManager: Component<APITokenManagerProps> = (props) => {
@ -67,16 +68,12 @@ export const APITokenManager: Component<APITokenManagerProps> = (props) => {
const trimmedName = nameInput().trim() || undefined; const trimmedName = nameInput().trim() || undefined;
const { token, record } = await SecurityAPI.createToken(trimmedName); const { token, record } = await SecurityAPI.createToken(trimmedName);
console.log('✅ Token generated:', { token, record });
setTokens((prev) => [record, ...prev]); setTokens((prev) => [record, ...prev]);
setNewTokenValue(token); setNewTokenValue(token);
setNewTokenRecord(record); setNewTokenRecord(record);
setNameInput(''); setNameInput('');
console.log('✅ State updated, newTokenValue:', token); showSuccess('New API token generated. Copy it below while it is still visible.');
showSuccess('New API token generated! Scroll up to see it!');
props.onTokensChanged?.(); props.onTokensChanged?.();
try { try {
@ -88,10 +85,6 @@ export const APITokenManager: Component<APITokenManagerProps> = (props) => {
console.warn('Unable to persist API token in localStorage', storageErr); console.warn('Unable to persist API token in localStorage', storageErr);
} }
// Scroll to top to show the token
setTimeout(() => {
window.scrollTo({ top: 0, behavior: 'smooth' });
}, 100);
} catch (err) { } catch (err) {
console.error('Failed to generate API token', err); console.error('Failed to generate API token', err);
showError('Failed to generate API token'); showError('Failed to generate API token');
@ -190,6 +183,16 @@ export const APITokenManager: Component<APITokenManagerProps> = (props) => {
</div> </div>
<div class="p-6 space-y-6"> <div class="p-6 space-y-6">
<Show when={props.refreshing}>
<div class="flex items-center gap-2 rounded-md bg-blue-50 dark:bg-blue-900/30 border border-blue-200 dark:border-blue-800 px-3 py-2 text-xs text-blue-800 dark:text-blue-200">
<svg class="w-4 h-4 animate-spin" viewBox="0 0 24 24" fill="none" stroke="currentColor">
<circle class="opacity-25" cx="12" cy="12" r="10" stroke-width="4" stroke="currentColor" />
<path class="opacity-75" d="M4 12a8 8 0 018-8" stroke-width="4" stroke-linecap="round" stroke="currentColor" />
</svg>
<span>Refreshing security status</span>
</div>
</Show>
{/* CRITICAL: Show generated token FIRST and PROMINENTLY */} {/* CRITICAL: Show generated token FIRST and PROMINENTLY */}
<Show when={newTokenValue()}> <Show when={newTokenValue()}>
<div class="space-y-4 border-4 border-green-500 dark:border-green-600 rounded-lg p-5 bg-green-50 dark:bg-green-900/30"> <div class="space-y-4 border-4 border-green-500 dark:border-green-600 rounded-lg p-5 bg-green-50 dark:bg-green-900/30">
@ -227,7 +230,7 @@ export const APITokenManager: Component<APITokenManagerProps> = (props) => {
<div class="bg-yellow-50 dark:bg-yellow-900/30 border border-yellow-300 dark:border-yellow-700 rounded-lg p-3"> <div class="bg-yellow-50 dark:bg-yellow-900/30 border border-yellow-300 dark:border-yellow-700 rounded-lg p-3">
<p class="text-sm text-yellow-900 dark:text-yellow-100 font-medium"> <p class="text-sm text-yellow-900 dark:text-yellow-100 font-medium">
💡 Next: Use this token on the <a href="/settings/docker-agents" class="underline hover:no-underline font-bold">Docker Agents</a> page to deploy monitoring. 💡 Keep this token safe and use it anywhere Pulse requires API authenticationDocker agents, automations, or custom integrations.
</p> </p>
</div> </div>

View file

@ -3574,7 +3574,6 @@ const Settings: Component<SettingsProps> = (props) => {
{/* Security setup now handled by first-run wizard */} {/* Security setup now handled by first-run wizard */}
{/* API Token - Show always to allow API access even when auth is disabled */} {/* API Token - Show always to allow API access even when auth is disabled */}
<Show when={!securityStatusLoading()}>
<Card <Card
padding="none" padding="none"
class="overflow-hidden border border-gray-200 dark:border-gray-700" class="overflow-hidden border border-gray-200 dark:border-gray-700"
@ -3614,10 +3613,10 @@ const Settings: Component<SettingsProps> = (props) => {
onTokensChanged={() => { onTokensChanged={() => {
void loadSecurityStatus(); void loadSecurityStatus();
}} }}
refreshing={securityStatusLoading()}
/> />
</div> </div>
</Card> </Card>
</Show>
{/* Advanced - Only show if auth is enabled */} {/* Advanced - Only show if auth is enabled */}
{/* Advanced Options section removed - was only used for Registration Tokens */} {/* Advanced Options section removed - was only used for Registration Tokens */}