From d4bf8001880a0fbeac82edf8290ad6bef2b64677 Mon Sep 17 00:00:00 2001 From: alphaeusmote <41258468-alphaeusmote@users.noreply.replit.com> Date: Thu, 10 Apr 2025 15:08:55 +0000 Subject: [PATCH] Fix dynamic group condition builder issues 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/f2b51f0f-fba7-47bc-9f6b-0f091ed578ae.jpg --- .../dynamic-groups/condition-builder.tsx | 73 +++++++++++++------ 1 file changed, 49 insertions(+), 24 deletions(-) diff --git a/client/src/components/dynamic-groups/condition-builder.tsx b/client/src/components/dynamic-groups/condition-builder.tsx index 2c7a272..8a5648e 100644 --- a/client/src/components/dynamic-groups/condition-builder.tsx +++ b/client/src/components/dynamic-groups/condition-builder.tsx @@ -159,24 +159,31 @@ const ConditionBuilder: React.FC = ({ } } - // Find just this group's children (not all groups with the same parent) - const childrenToRemove = getAllDescendants(conditionToRemove.id); - - // Create a list of IDs to remove (the group and all its descendants) - const idsToRemove = new Set([ - conditionToRemove.id, - ...childrenToRemove.map(c => c.id).filter(Boolean) - ]); - - // Only remove this specific group and its descendants - const newConditions = conditions.filter(c => { - // Keep the condition if its ID is not in our removal list - // and its parent ID is not in our removal list - return !idsToRemove.has(c.id) && - !idsToRemove.has(c.parentId); - }); - - onChange(newConditions); + // Make sure we have a valid ID before proceeding + if (conditionToRemove.id !== undefined) { + // Find just this group's children (not all groups with the same parent) + const childrenToRemove = getAllDescendants(conditionToRemove.id); + + // Create a list of IDs to remove (the group and all its descendants) + const idsToRemove = new Set([ + conditionToRemove.id, + ...childrenToRemove.map(c => c.id).filter((id): id is number => id !== undefined) + ]); + + // Only remove this specific group and its descendants + const newConditions = conditions.filter(c => { + // Keep the condition if its ID is not in our removal list + // and its parent ID is not in our removal list + return !idsToRemove.has(c.id) && + !idsToRemove.has(c.parentId); + }); + + onChange(newConditions); + } else { + // No valid ID, just remove the condition at this index + const newConditions = conditions.filter((c, i) => i !== index); + onChange(newConditions); + } } else { // Just remove the single condition, more carefully const newConditions = conditions.filter((c, i) => i !== index); @@ -185,13 +192,15 @@ const ConditionBuilder: React.FC = ({ }; // Helper function to get all descendants of a condition group - const getAllDescendants = (parentId: number): Condition[] => { + const getAllDescendants = (parentId: number | undefined): Condition[] => { + if (parentId === undefined) return []; + const directChildren = conditions.filter(c => c.parentId === parentId); // Get all children of groups within this group (recursively) const groupChildren = directChildren - .filter(c => c.isGroup && c.id) - .flatMap(group => getAllDescendants(group.id!)); + .filter(c => c.isGroup && c.id !== undefined) + .flatMap(group => getAllDescendants(group.id)); return [...directChildren, ...groupChildren]; }; @@ -386,7 +395,15 @@ const ConditionBuilder: React.FC = ({ className="mt-1" placeholder="Enter custom attribute" value={condition.customAttribute || ''} - onChange={(e) => updateCondition(index, 'customAttribute', e.target.value)} + onChange={(e) => { + // Use direct update to prevent focus loss + const newConditions = [...conditions]; + newConditions[index] = { + ...newConditions[index], + customAttribute: e.target.value + }; + onChange(newConditions); + }} /> )} @@ -413,8 +430,16 @@ const ConditionBuilder: React.FC = ({ {condition.operator !== 'present' && condition.operator !== 'notPresent' && ( updateCondition(index, 'value', e.target.value)} + value={condition.value || ''} + onChange={(e) => { + // Use a direct update approach for text inputs to prevent focus loss + const newConditions = [...conditions]; + newConditions[index] = { + ...newConditions[index], + value: e.target.value + }; + onChange(newConditions); + }} /> )}