Skip to content

Commit c3ce404

Browse files
committed
Add disconnect functionality to ConnectNodeModal with hover-to-reveal buttons
1 parent dd27d89 commit c3ce404

1 file changed

Lines changed: 80 additions & 4 deletions

File tree

packages/web/src/components/ConnectNodeModal.tsx

Lines changed: 80 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { useState, useEffect } from 'react';
2-
import { X, Link2, Search, CheckCircle, ArrowRight, Target, ExternalLink, Filter, ChevronDown, CheckCircle2 } from 'lucide-react';
2+
import { X, Link2, Search, CheckCircle, ArrowRight, Target, ExternalLink, Filter, ChevronDown, CheckCircle2, Trash2 } from 'lucide-react';
33
import { useQuery, useMutation } from '@apollo/client';
4-
import { GET_WORK_ITEMS, CREATE_EDGE, GET_EDGES } from '../lib/queries';
4+
import { GET_WORK_ITEMS, CREATE_EDGE, GET_EDGES, DELETE_EDGE } from '../lib/queries';
55
import { useAuth } from '../contexts/AuthContext';
66
import { useGraph } from '../contexts/GraphContext';
77
import { useNotifications } from '../contexts/NotificationContext';
@@ -123,6 +123,34 @@ export function ConnectNodeModal({ isOpen, onClose, sourceNode }: ConnectNodeMod
123123
awaitRefetchQueries: true
124124
});
125125

126+
const [deleteEdgeMutation, { loading: deletingConnection }] = useMutation(DELETE_EDGE, {
127+
refetchQueries: [
128+
// Refetch edges for the source node
129+
{
130+
query: GET_EDGES,
131+
variables: {
132+
where: {
133+
OR: [
134+
{ source: { id: sourceNode.id } },
135+
{ target: { id: sourceNode.id } }
136+
]
137+
}
138+
}
139+
},
140+
// Refetch all edges for graph visualization
141+
{
142+
query: GET_EDGES,
143+
variables: {}
144+
},
145+
// Refetch work items
146+
{
147+
query: GET_WORK_ITEMS,
148+
variables: { options: { limit: 100 } }
149+
}
150+
],
151+
awaitRefetchQueries: true
152+
});
153+
126154
// Initialize data arrays
127155
const workItems: WorkItem[] = workItemsData?.workItems || [];
128156
const existingEdges: Edge[] = edgesData?.edges || [];
@@ -284,6 +312,37 @@ export function ConnectNodeModal({ isOpen, onClose, sourceNode }: ConnectNodeMod
284312
}
285313
};
286314

315+
const handleDisconnectEdge = async (connectionId: string, connectedNodeTitle: string, relationshipType: string) => {
316+
try {
317+
console.log('Disconnecting edge:', { connectionId, connectedNodeTitle, relationshipType });
318+
319+
await deleteEdgeMutation({
320+
variables: {
321+
where: { id: connectionId }
322+
}
323+
});
324+
325+
showSuccess(
326+
'Connection Removed Successfully!',
327+
`Disconnected "${sourceNode.title}" from "${connectedNodeTitle}"`
328+
);
329+
330+
} catch (error: any) {
331+
console.error('Failed to disconnect:', error);
332+
333+
let errorMessage = 'Please try again or contact support.';
334+
if (error.graphQLErrors && error.graphQLErrors.length > 0) {
335+
errorMessage = error.graphQLErrors[0].message;
336+
} else if (error.networkError) {
337+
errorMessage = 'Network error. Please check your connection.';
338+
} else if (error.message) {
339+
errorMessage = error.message;
340+
}
341+
342+
showError('Failed to Remove Connection', errorMessage);
343+
}
344+
};
345+
287346
const selectedRelation = RELATIONSHIP_TYPES.find(r => r.type === selectedRelationType);
288347

289348
return (
@@ -675,6 +734,22 @@ export function ConnectNodeModal({ isOpen, onClose, sourceNode }: ConnectNodeMod
675734
<span className="text-gray-200 font-medium text-xs max-w-16 truncate">{connection.connectedNode.title}</span>
676735
</div>
677736
</div>
737+
738+
{/* Disconnect Button - Only show for Edge entities (not WorkItem dependencies) */}
739+
{connection.id.startsWith('edge-') || (!connection.id.startsWith('workitem-')) ? (
740+
<button
741+
onClick={() => handleDisconnectEdge(connection.id, connection.connectedNode.title, connection.type)}
742+
disabled={deletingConnection}
743+
className="opacity-0 group-hover:opacity-100 transition-opacity duration-200 p-2 rounded-lg bg-red-500/20 hover:bg-red-500/30 border border-red-400/30 hover:border-red-400/50 disabled:opacity-50 disabled:cursor-not-allowed"
744+
title={`Disconnect ${relationshipType?.label || connection.type} relationship`}
745+
>
746+
<Trash2 className="h-3 w-3 text-red-400" />
747+
</button>
748+
) : (
749+
<div className="text-xs text-gray-500 px-2 py-1 rounded bg-gray-600/20 border border-gray-600/30">
750+
Legacy
751+
</div>
752+
)}
678753
</div>
679754
);
680755
})}
@@ -808,7 +883,7 @@ export function ConnectNodeModal({ isOpen, onClose, sourceNode }: ConnectNodeMod
808883
</div>
809884
<span className="text-gray-400"></span>
810885
<span className="text-gray-300 font-medium">{node.type}</span>
811-
{node.priorityComp && (
886+
{(node.priorityComp !== undefined && node.priorityComp !== null) && (
812887
<>
813888
<span className="text-gray-400"></span>
814889
<span className="text-emerald-300 font-medium">{Math.round(node.priorityComp * 100)}%</span>
@@ -842,13 +917,14 @@ export function ConnectNodeModal({ isOpen, onClose, sourceNode }: ConnectNodeMod
842917
</button>
843918
<button
844919
onClick={handleCreateConnections}
845-
disabled={selectedNodes.size === 0 || creatingConnection || isRelationshipDisabled(selectedRelationType)}
920+
disabled={selectedNodes.size === 0 || creatingConnection || deletingConnection || isRelationshipDisabled(selectedRelationType)}
846921
className="px-8 py-3 bg-gradient-to-r from-emerald-600 to-green-700 hover:from-emerald-500 hover:to-green-600 text-white rounded-xl transition-all duration-200 disabled:opacity-50 disabled:cursor-not-allowed flex items-center space-x-3 font-semibold shadow-lg shadow-emerald-500/20 disabled:shadow-none"
847922
title={isRelationshipDisabled(selectedRelationType) ? 'This relationship already exists between the selected nodes' : ''}
848923
>
849924
<Link2 className="w-5 h-5" />
850925
<span>
851926
{creatingConnection ? 'Connecting...' :
927+
deletingConnection ? 'Removing connection...' :
852928
isRelationshipDisabled(selectedRelationType) ? 'Already Connected' :
853929
`Connect ${selectedNodes.size} Node${selectedNodes.size !== 1 ? 's' : ''}`}
854930
</span>

0 commit comments

Comments
 (0)