feat: use select dropdowns for target role/group in claim mapping editor
Populate target field from existing roles (assign role) or groups (add to group) instead of free-text input, preventing typos. Switching action resets the target selection. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -9,6 +9,7 @@ import {
|
||||
useTestClaimMappingRules,
|
||||
} from '../../api/queries/admin/claim-mappings';
|
||||
import type { ClaimMappingRule, TestResponse } from '../../api/queries/admin/claim-mappings';
|
||||
import { useRoles, useGroups } from '../../api/queries/admin/rbac';
|
||||
import styles from './ClaimMappingRulesModal.module.css';
|
||||
|
||||
const MATCH_OPTIONS = [
|
||||
@@ -60,6 +61,17 @@ export default function ClaimMappingRulesModal({ open, onClose }: Props) {
|
||||
const [testResult, setTestResult] = useState<TestResponse | null>(null);
|
||||
const [testError, setTestError] = useState('');
|
||||
|
||||
// Roles and groups for target dropdown
|
||||
const { data: roles = [] } = useRoles(open);
|
||||
const { data: groups = [] } = useGroups(open);
|
||||
|
||||
const roleOptions = roles.map((r) => ({ value: r.name, label: r.name }));
|
||||
const groupOptions = groups.map((g) => ({ value: g.name, label: g.name }));
|
||||
|
||||
function targetOptions(action: string) {
|
||||
return action === 'assignRole' ? roleOptions : groupOptions;
|
||||
}
|
||||
|
||||
if (!open) return null;
|
||||
|
||||
const sorted = [...rules].sort((a, b) => a.priority - b.priority);
|
||||
@@ -230,8 +242,8 @@ export default function ClaimMappingRulesModal({ open, onClose }: Props) {
|
||||
<td><Input value={editForm.claim} onChange={(e) => setEditForm({ ...editForm, claim: e.target.value })} className={styles.claimInput} /></td>
|
||||
<td><Select options={MATCH_OPTIONS} value={editForm.matchType} onChange={(e) => setEditForm({ ...editForm, matchType: e.target.value })} /></td>
|
||||
<td><Input value={editForm.matchValue} onChange={(e) => setEditForm({ ...editForm, matchValue: e.target.value })} /></td>
|
||||
<td><Select options={ACTION_OPTIONS} value={editForm.action} onChange={(e) => setEditForm({ ...editForm, action: e.target.value })} /></td>
|
||||
<td><Input value={editForm.target} onChange={(e) => setEditForm({ ...editForm, target: e.target.value })} /></td>
|
||||
<td><Select options={ACTION_OPTIONS} value={editForm.action} onChange={(e) => setEditForm({ ...editForm, action: e.target.value, target: '' })} /></td>
|
||||
<td><Select options={targetOptions(editForm.action)} value={editForm.target} onChange={(e) => setEditForm({ ...editForm, target: e.target.value })} /></td>
|
||||
<td>
|
||||
<div className={styles.actions}>
|
||||
<button className={styles.iconBtn} onClick={() => saveEdit(rule)} title="Save"><Check size={14} /></button>
|
||||
@@ -272,13 +284,8 @@ export default function ClaimMappingRulesModal({ open, onClose }: Props) {
|
||||
<Input placeholder="Claim name" value={addForm.claim} onChange={(e) => setAddForm({ ...addForm, claim: e.target.value })} className={styles.claimInput} />
|
||||
<Select options={MATCH_OPTIONS} value={addForm.matchType} onChange={(e) => setAddForm({ ...addForm, matchType: e.target.value })} className={styles.matchSelect} />
|
||||
<Input placeholder="Match value" value={addForm.matchValue} onChange={(e) => setAddForm({ ...addForm, matchValue: e.target.value })} className={styles.valueInput} />
|
||||
<Select options={ACTION_OPTIONS} value={addForm.action} onChange={(e) => setAddForm({ ...addForm, action: e.target.value })} className={styles.actionSelect} />
|
||||
<Input
|
||||
placeholder={addForm.action === 'assignRole' ? 'Role name' : 'Group name'}
|
||||
value={addForm.target}
|
||||
onChange={(e) => setAddForm({ ...addForm, target: e.target.value })}
|
||||
className={styles.targetInput}
|
||||
/>
|
||||
<Select options={ACTION_OPTIONS} value={addForm.action} onChange={(e) => setAddForm({ ...addForm, action: e.target.value, target: '' })} className={styles.actionSelect} />
|
||||
<Select options={targetOptions(addForm.action)} value={addForm.target} onChange={(e) => setAddForm({ ...addForm, target: e.target.value })} className={styles.targetInput} />
|
||||
<Button size="sm" variant="primary" onClick={handleAdd} disabled={addDisabled} loading={createRule.isPending}>+ Add</Button>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user