diff --git a/client/src/components/dynamic-groups/rule-editor.tsx b/client/src/components/dynamic-groups/rule-editor.tsx index e2a00a1..56317d3 100644 --- a/client/src/components/dynamic-groups/rule-editor.tsx +++ b/client/src/components/dynamic-groups/rule-editor.tsx @@ -54,7 +54,9 @@ export const RuleEditor: React.FC = ({ rule, onSave, onCancel } const [formData, setFormData] = useState({ name: rule?.name || '', description: rule?.description || '', - targetGroup: rule?.targetGroup || '', + targetGroupName: rule?.targetGroup ? rule?.targetGroup.split(',')[0].replace('CN=', '') : '', + targetOU: rule?.targetGroup ? rule?.targetGroup.split(',').slice(1).join(',') : '', + createGroupIfNotExists: false, enabled: rule?.enabled ?? true, variablePattern: rule?.variablePattern || '', connections: rule?.connectionIds || [] @@ -109,6 +111,12 @@ export const RuleEditor: React.FC = ({ rule, onSave, onCancel } setFormData(prev => ({ ...prev, connections: connectionIds })); }; + // Compute the full target group DN + const getTargetGroupDN = () => { + if (!formData.targetGroupName || !formData.targetOU) return ''; + return `CN=${formData.targetGroupName},${formData.targetOU}`; + }; + // Handle form submission const handleSubmit = () => { if (!formData.name) { @@ -121,10 +129,20 @@ export const RuleEditor: React.FC = ({ rule, onSave, onCancel } return; } - if (!formData.targetGroup) { + if (!formData.targetGroupName) { toast({ title: "Missing Information", - description: "Please specify a target AD group", + description: "Please specify a target AD group name", + variant: "destructive" + }); + setActiveTab('general'); + return; + } + + if (!formData.targetOU) { + toast({ + title: "Missing Information", + description: "Please specify the organizational unit for the target group", variant: "destructive" }); setActiveTab('general'); @@ -161,18 +179,21 @@ export const RuleEditor: React.FC = ({ rule, onSave, onCancel } return; } + const targetGroupDN = getTargetGroupDN(); + const ruleData: DynamicGroupRule = { id: rule?.id, name: formData.name, description: formData.description || null, - targetGroup: formData.targetGroup, + targetGroup: targetGroupDN, enabled: formData.enabled, createdAt: rule?.createdAt || new Date(), updatedAt: new Date(), lastRun: rule?.lastRun || null, lastRunStatus: rule?.lastRunStatus || null, variablePattern: formData.variablePattern || null, - connectionIds: formData.connections + connectionIds: formData.connections, + createGroupIfNotExists: formData.createGroupIfNotExists }; onSave(ruleData, schedules); @@ -181,12 +202,14 @@ export const RuleEditor: React.FC = ({ rule, onSave, onCancel } // Test the rule const testRuleMutation = useMutation({ mutationFn: async () => { + const targetGroupDN = getTargetGroupDN(); const res = await apiRequest('POST', '/api/dynamic-group-rules/test', { rule: { name: formData.name, - targetGroup: formData.targetGroup, + targetGroup: targetGroupDN, connectionIds: formData.connections, - variablePattern: formData.variablePattern || null + variablePattern: formData.variablePattern || null, + createGroupIfNotExists: formData.createGroupIfNotExists }, conditions }); @@ -259,6 +282,39 @@ export const RuleEditor: React.FC = ({ rule, onSave, onCancel } Configure the basic settings for your dynamic group rule +
+ +
+ {ldapConnections.length === 0 ? ( +

No LDAP connections available. Please create one first.

+ ) : ( +
+ {ldapConnections.map((connection) => ( +
+ { + if (checked) { + handleConnectionChange([...formData.connections, connection.id]); + } else { + handleConnectionChange(formData.connections.filter(id => id !== connection.id)); + } + }} + /> + +
+ ))} +
+ )} +
+

+ Select one or more LDAP connections to search for objects +

+
+
@@ -272,18 +328,63 @@ export const RuleEditor: React.FC = ({ rule, onSave, onCancel }
- - Description +