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,
|
useTestClaimMappingRules,
|
||||||
} from '../../api/queries/admin/claim-mappings';
|
} from '../../api/queries/admin/claim-mappings';
|
||||||
import type { ClaimMappingRule, TestResponse } 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';
|
import styles from './ClaimMappingRulesModal.module.css';
|
||||||
|
|
||||||
const MATCH_OPTIONS = [
|
const MATCH_OPTIONS = [
|
||||||
@@ -60,6 +61,17 @@ export default function ClaimMappingRulesModal({ open, onClose }: Props) {
|
|||||||
const [testResult, setTestResult] = useState<TestResponse | null>(null);
|
const [testResult, setTestResult] = useState<TestResponse | null>(null);
|
||||||
const [testError, setTestError] = useState('');
|
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;
|
if (!open) return null;
|
||||||
|
|
||||||
const sorted = [...rules].sort((a, b) => a.priority - b.priority);
|
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><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><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><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><Select options={ACTION_OPTIONS} value={editForm.action} onChange={(e) => setEditForm({ ...editForm, action: e.target.value, target: '' })} /></td>
|
||||||
<td><Input value={editForm.target} onChange={(e) => setEditForm({ ...editForm, target: e.target.value })} /></td>
|
<td><Select options={targetOptions(editForm.action)} value={editForm.target} onChange={(e) => setEditForm({ ...editForm, target: e.target.value })} /></td>
|
||||||
<td>
|
<td>
|
||||||
<div className={styles.actions}>
|
<div className={styles.actions}>
|
||||||
<button className={styles.iconBtn} onClick={() => saveEdit(rule)} title="Save"><Check size={14} /></button>
|
<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} />
|
<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} />
|
<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} />
|
<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} />
|
<Select options={ACTION_OPTIONS} value={addForm.action} onChange={(e) => setAddForm({ ...addForm, action: e.target.value, target: '' })} className={styles.actionSelect} />
|
||||||
<Input
|
<Select options={targetOptions(addForm.action)} value={addForm.target} onChange={(e) => setAddForm({ ...addForm, target: e.target.value })} className={styles.targetInput} />
|
||||||
placeholder={addForm.action === 'assignRole' ? 'Role name' : 'Group name'}
|
|
||||||
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>
|
<Button size="sm" variant="primary" onClick={handleAdd} disabled={addDisabled} loading={createRule.isPending}>+ Add</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user