Improve dynamic group condition builder with custom attribute support and enhanced LDAP filter generation

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 705f2157-ef97-4fbd-89e4-8c7f2ecaea90
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/7ed01c5f-a82d-405a-b728-b2e3d127c60c/e08391da-50e7-4d65-9ce9-fa26d31e7e6a.jpg
This commit is contained in:
alphaeusmote
2025-04-10 11:55:48 +00:00
parent 03ff505e2d
commit 3b739b032d
3 changed files with 28 additions and 16 deletions
@@ -85,9 +85,11 @@ const ConditionBuilder: React.FC<ConditionBuilderProps> = ({
// Update available attributes when data is loaded // Update available attributes when data is loaded
useEffect(() => { useEffect(() => {
if (attributesData.length > 0) { if (attributesData.length > 0) {
setAvailableAttributes([ // Extract unique attribute names
...new Set(attributesData.map(attr => attr.name)) const uniqueAttributes = Array.from(
]); new Set(attributesData.map(attr => attr.name))
);
setAvailableAttributes(uniqueAttributes);
} }
}, [attributesData]); }, [attributesData]);
@@ -137,7 +139,11 @@ const ConditionBuilder: React.FC<ConditionBuilderProps> = ({
// Automatically expand the new group // Automatically expand the new group
if (newGroup.id) { if (newGroup.id) {
setExpandedGroups(prev => new Set([...prev, newGroup.id!])); setExpandedGroups(prev => {
const expanded = new Set(prev);
expanded.add(newGroup.id!);
return expanded;
});
} }
} }
}; };
@@ -591,24 +597,29 @@ const generateLdapFilter = (conditions: Condition[]): string => {
return `(${operator}${childFilters})`; return `(${operator}${childFilters})`;
} else { } else {
// Get actual attribute name (custom or selected)
const attributeName = condition.attribute === 'custom' && condition.customAttribute
? condition.customAttribute
: condition.attribute;
// Regular condition // Regular condition
switch (condition.operator) { switch (condition.operator) {
case '=': case '=':
return `(${condition.attribute}=${condition.value})`; return `(${attributeName}=${condition.value})`;
case '!=': case '!=':
return `(!(${condition.attribute}=${condition.value}))`; return `(!(${attributeName}=${condition.value}))`;
case 'contains': case 'contains':
return `(${condition.attribute}=*${condition.value}*)`; return `(${attributeName}=*${condition.value}*)`;
case 'startsWith': case 'startsWith':
return `(${condition.attribute}=${condition.value}*)`; return `(${attributeName}=${condition.value}*)`;
case 'endsWith': case 'endsWith':
return `(${condition.attribute}=*${condition.value})`; return `(${attributeName}=*${condition.value})`;
case 'present': case 'present':
return `(${condition.attribute}=*)`; return `(${attributeName}=*)`;
case 'notPresent': case 'notPresent':
return `(!(${condition.attribute}=*))`; return `(!(${attributeName}=*))`;
default: default:
return `(${condition.attribute}=${condition.value})`; return `(${attributeName}=${condition.value})`;
} }
} }
}; };
@@ -33,6 +33,7 @@ export interface Condition {
ruleId?: number; ruleId?: number;
parentId?: number | null; parentId?: number | null;
attribute: string; attribute: string;
customAttribute?: string;
operator: string; operator: string;
value: string; value: string;
logicalOperator?: string | null; logicalOperator?: string | null;
@@ -337,11 +338,11 @@ export const RuleEditor: React.FC<RuleEditorProps> = ({ rule, onSave, onCancel }
name="variablePattern" name="variablePattern"
value={formData.variablePattern} value={formData.variablePattern}
onChange={handleInputChange} onChange={handleInputChange}
placeholder="e.g., {attribute} Value" placeholder="e.g., &#123;attributeName&#125; Value"
/> />
<p className="text-xs text-muted-foreground"> <p className="text-xs text-muted-foreground">
Optional pattern for generating variable values in name or description. Optional pattern for generating variable values in name or description.
Use {attribute} to insert attribute values. Use &#123;attributeName&#125; to insert attribute values.
</p> </p>
</div> </div>
+2 -2
View File
@@ -348,9 +348,9 @@ export default function SettingsPage() {
<div className="space-y-2"> <div className="space-y-2">
<Label htmlFor="ldap-search-filter">Search Filter</Label> <Label htmlFor="ldap-search-filter">Search Filter</Label>
<Input id="ldap-search-filter" placeholder="(uid={{username}})" /> <Input id="ldap-search-filter" placeholder="(uid=&#123;&#123;username&#125;&#125;)" />
<p className="text-xs text-muted-foreground"> <p className="text-xs text-muted-foreground">
Use {{username}} as a placeholder for the user's input Use &#123;&#123;username&#125;&#125; as a placeholder for the user's input
</p> </p>
</div> </div>