()
| 59 | } |
| 60 | |
| 61 | export function ApiKeysManager() { |
| 62 | const roles = useAuthStore((state) => state.roles); |
| 63 | const canManageKeys = hasAdminRole(roles); |
| 64 | const isReadOnly = !canManageKeys; |
| 65 | |
| 66 | const apiKeys = useApiKeyStore((state) => state.apiKeys); |
| 67 | const loading = useApiKeyStore((state) => state.loading); |
| 68 | const error = useApiKeyStore((state) => state.error); |
| 69 | const fetchApiKeys = useApiKeyStore((state) => state.fetchApiKeys); |
| 70 | const createApiKey = useApiKeyStore((state) => state.createApiKey); |
| 71 | const revokeApiKey = useApiKeyStore((state) => state.revokeApiKey); |
| 72 | const deleteApiKey = useApiKeyStore((state) => state.deleteApiKey); |
| 73 | const lastCreatedKey = useApiKeyStore((state) => state.lastCreatedKey); |
| 74 | const clearLastCreatedKey = useApiKeyStore((state) => state.clearLastCreatedKey); |
| 75 | |
| 76 | const [isCreateOpen, setIsCreateOpen] = useState(false); |
| 77 | const [formState, setFormState] = useState<CreateApiKeyInput>(INITIAL_FORM); |
| 78 | const [createError, setCreateError] = useState<string | null>(null); |
| 79 | const [isSubmitting, setIsSubmitting] = useState(false); |
| 80 | |
| 81 | const [successMessage, setSuccessMessage] = useState<string | null>(null); |
| 82 | |
| 83 | // Revoke/Delete Confirmation |
| 84 | const [confirmAction, setConfirmAction] = useState<{ |
| 85 | type: 'revoke' | 'delete'; |
| 86 | target: ApiKeyResponseDto; |
| 87 | } | null>(null); |
| 88 | |
| 89 | useEffect(() => { |
| 90 | fetchApiKeys().catch(console.error); |
| 91 | }, [fetchApiKeys]); |
| 92 | |
| 93 | const handleCreateOpenChange = (open: boolean) => { |
| 94 | setIsCreateOpen(open); |
| 95 | if (!open) { |
| 96 | setFormState(INITIAL_FORM); |
| 97 | setCreateError(null); |
| 98 | clearLastCreatedKey(); // Clear sensitive key if dialog closed |
| 99 | } |
| 100 | }; |
| 101 | |
| 102 | const handleInputChange = (field: keyof CreateApiKeyInput, value: any) => { |
| 103 | setFormState((prev) => ({ |
| 104 | ...prev, |
| 105 | [field]: value, |
| 106 | })); |
| 107 | }; |
| 108 | |
| 109 | const handlePermissionChange = ( |
| 110 | category: 'workflows' | 'runs', |
| 111 | action: string, |
| 112 | checked: boolean, |
| 113 | ) => { |
| 114 | setFormState((prev) => ({ |
| 115 | ...prev, |
| 116 | permissions: { |
| 117 | ...prev.permissions, |
| 118 | [category]: { |
nothing calls this directly
no test coverage detected