import React from 'react' import type { IamPrimitives } from '../../core/types' import { JsonTree } from '../components/json-tree' import { DetailEmpty, Section, SplitView } from '../components/layout' import { Alert, Badge, Button, Field, Input, TextArea } from '../components/ui' import { safeParseJson } from '../lib/format' import type { IamIDevtoolsEngine } from '../lib/types' export function IamSubjectsPanel({ engine }: { engine: IamIDevtoolsEngine }) { const [subjectId, setSubjectId] = React.useState('') const [attrs, setAttrs] = React.useState(null) const [attrsDraft, setAttrsDraft] = React.useState('{}') const [roleId, setRoleId] = React.useState('') const [scope, setScope] = React.useState('') const [busy, setBusy] = React.useState(false) const [error, setError] = React.useState(null) const [status, setStatus] = React.useState(null) async function load() { setError(null) setStatus(null) if (!subjectId) return setError('subject id required') setBusy(true) try { const a = await engine.admin.getAttributes(subjectId) setAttrs(a) setAttrsDraft(JSON.stringify(a, null, 2)) } catch (err) { setError(err instanceof Error ? err.message : String(err)) } finally { setBusy(false) } } async function saveAttrs() { setError(null) setStatus(null) const parsed = safeParseJson(attrsDraft, {}) if (parsed.error) return setError(`attributes JSON: ${parsed.error}`) setBusy(true) try { await engine.admin.setAttributes(subjectId, parsed.value) setAttrs(parsed.value) setStatus('attributes saved') } catch (err) { setError(err instanceof Error ? err.message : String(err)) } finally { setBusy(false) } } async function assign() { setError(null) setStatus(null) if (!roleId) return setError('role id required') setBusy(true) try { await engine.admin.assignRole(subjectId, roleId, scope || undefined) setStatus(`assigned ${roleId}${scope ? ` @ ${scope}` : ''}`) } catch (err) { setError(err instanceof Error ? err.message : String(err)) } finally { setBusy(false) } } async function revoke() { setError(null) setStatus(null) if (!roleId) return setError('role id required') setBusy(true) try { await engine.admin.revokeRole(subjectId, roleId, scope || undefined) setStatus(`revoked ${roleId}${scope ? ` @ ${scope}` : ''}`) } catch (err) { setError(err instanceof Error ? err.message : String(err)) } finally { setBusy(false) } } return (

Lookup

setSubjectId(e.target.value)} placeholder="user-1" value={subjectId} /> {error && {error}} {status && {status}} {attrs && (
{Object.keys(attrs).length} attrs
)}
} right={ !subjectId ? ( ) : (
{subjectId}
{attrs ? ( ) : (

Load to view.

)}