Skip to content

Commit 4581d56

Browse files
authored
Merge pull request #284 from FalkorDB/fix-create-path
Fix #283 enable select node only after input display
2 parents 9987792 + d6966a5 commit 4581d56

File tree

2 files changed

+63
-31
lines changed

2 files changed

+63
-31
lines changed

app/components/Input.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ export default function Input({ value, onValueChange, handleSubmit, graph, icon,
3333
}, [open])
3434

3535
useEffect(() => {
36+
if (!graph.Id) return
37+
3638
let isLastRequest = true
3739
const timeout = setTimeout(async () => {
3840

@@ -75,7 +77,7 @@ export default function Input({ value, onValueChange, handleSubmit, graph, icon,
7577
clearTimeout(timeout)
7678
isLastRequest = false
7779
}
78-
}, [value])
80+
}, [value, graph.Id])
7981

8082
const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
8183
const container = containerRef.current

app/components/chat.tsx

Lines changed: 60 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ interface Message {
6969
type: MessageTypes;
7070
text?: string;
7171
paths?: { nodes: any[], edges: any[] }[];
72+
graphName?: string;
7273
}
7374

7475
interface Props {
@@ -92,47 +93,52 @@ const SUGGESTIONS = [
9293

9394
const RemoveLastPath = (messages: Message[]) => {
9495
const index = messages.findIndex((m) => m.type === MessageTypes.Path)
95-
96+
9697
if (index !== -1) {
9798
messages = [...messages.slice(0, index - 2), ...messages.slice(index + 1)];
9899
messages = RemoveLastPath(messages)
99100
}
100-
101+
101102
return messages
102103
}
103104

104105
export function Chat({ repo, path, setPath, graph, chartRef, selectedPathId, isPath, setIsPath }: Props) {
105-
106+
106107
// Holds the messages in the chat
107108
const [messages, setMessages] = useState<Message[]>([]);
108-
109+
109110
// Holds the messages in the chat
110111
const [paths, setPaths] = useState<{ nodes: any[], edges: any[] }[]>([]);
111-
112+
112113
const [selectedPath, setSelectedPath] = useState<{ nodes: any[], edges: any[] }>();
113-
114+
114115
// Holds the user input while typing
115116
const [query, setQuery] = useState('');
116-
117+
117118
const [isPathResponse, setIsPathResponse] = useState(false);
118-
119+
119120
const [tipOpen, setTipOpen] = useState(false);
120-
121+
121122
const [sugOpen, setSugOpen] = useState(false);
122-
123+
123124
// A reference to the chat container to allow scrolling to the bottom
124125
const containerRef: React.RefObject<HTMLDivElement> = useRef(null);
125-
126+
126127
const isSendMessage = messages.some(m => m.type === MessageTypes.Pending) || (messages.some(m => m.text === "Please select a starting point and the end point. Select or press relevant item on the graph") && !messages.some(m => m.type === MessageTypes.Path))
127-
128+
129+
useEffect(() => {
130+
setSelectedPath(undefined)
131+
setIsPathResponse(false)
132+
}, [graph.Id])
133+
128134
useEffect(() => {
129135
const p = paths.find((path) => [...path.edges, ...path.nodes].some((e: any) => e.id === selectedPathId))
130-
136+
131137
if (!p) return
132-
138+
133139
handleSetSelectedPath(p)
134140
}, [selectedPathId])
135-
141+
136142
// Scroll to the bottom of the chat on new message
137143
useEffect(() => {
138144
setTimeout(() => {
@@ -202,14 +208,28 @@ export function Chat({ repo, path, setPath, graph, chartRef, selectedPathId, isP
202208
})
203209
chart.elements().filter(el => [...p.nodes, ...p.edges].some(e => e.id == el.id())).layout(LAYOUT).run();
204210
} else {
205-
chart.elements().filter(el => [...p.nodes, ...p.edges].some(e => e.id == el.id())).forEach(el => {
206-
if (el.id() == p.nodes[0].id || el.id() == p.nodes[p.nodes.length - 1].id) {
207-
el.removeStyle().style(SELECTED_PATH_NODE_STYLE);
208-
} else if (el.isNode()) {
209-
el.removeStyle().style(PATH_NODE_STYLE);
211+
const elements: any = { nodes: [], edges: [] };
212+
213+
[...p.nodes, ...p.edges].forEach(e => {
214+
let element = chart.elements(`#${e.id}`)
215+
if (element.length === 0) {
216+
const type = "src_node" in e
217+
e = type ? { ...e, id: e.id.slice(1) } : e
218+
type
219+
? elements.edges.push(e)
220+
: elements.nodes.push(e)
210221
}
211-
if (el.isEdge()) {
212-
el.removeStyle().style(SELECTED_PATH_EDGE_STYLE);
222+
})
223+
224+
chart.add(graph.extend(elements))
225+
chart.elements().filter((e) => [...p.nodes, ...p.edges].some((el) => el.id == e.id())).forEach((e) => {
226+
if (e.id() == p.nodes[0].id || e.id() == p.nodes[p.nodes.length - 1].id) {
227+
e.removeStyle().style(SELECTED_PATH_NODE_STYLE);
228+
} else if (e.isNode()) {
229+
e.removeStyle().style(PATH_NODE_STYLE);
230+
}
231+
if (e.isEdge()) {
232+
e.removeStyle().style(SELECTED_PATH_EDGE_STYLE);
213233
}
214234
}).layout(LAYOUT).run();
215235
}
@@ -329,7 +349,7 @@ export function Chat({ repo, path, setPath, graph, chartRef, selectedPathId, isP
329349
});
330350
elements.layout(LAYOUT).run()
331351
setPaths(formattedPaths)
332-
setMessages((prev) => [...RemoveLastPath(prev), { type: MessageTypes.PathResponse, paths: formattedPaths }]);
352+
setMessages((prev) => [...RemoveLastPath(prev), { type: MessageTypes.PathResponse, paths: formattedPaths, graphName: graph.Id }]);
333353
setPath(undefined)
334354
setIsPathResponse(true)
335355
}
@@ -341,7 +361,6 @@ export function Chat({ repo, path, setPath, graph, chartRef, selectedPathId, isP
341361
className="Tip"
342362
onClick={() => {
343363
setTipOpen(false)
344-
setPath({})
345364
setMessages(prev => [
346365
...RemoveLastPath(prev),
347366
{ type: MessageTypes.Query, text: "Create a path" },
@@ -356,7 +375,10 @@ export function Chat({ repo, path, setPath, graph, chartRef, selectedPathId, isP
356375
type: MessageTypes.Response,
357376
text: "Please select a starting point and the end point. Select or press relevant item on the graph"
358377
}]), 300)
359-
setTimeout(() => setMessages(prev => [...prev, { type: MessageTypes.Path }]), 4000)
378+
setTimeout(() => {
379+
setPath({})
380+
setMessages(prev => [...prev, { type: MessageTypes.Path }])
381+
}, 4000)
360382
}}
361383
>
362384
<Lightbulb />
@@ -431,14 +453,22 @@ export function Chat({ repo, path, setPath, graph, chartRef, selectedPathId, isP
431453
message.paths.map((p, i: number) => (
432454
<button
433455
key={i}
434-
className={cn("flex text-wrap border p-2 gap-2 rounded-md", p.nodes.length === selectedPath?.nodes.length && selectedPath?.nodes.every(node => p?.nodes.some((n) => n.id === node.id)) && "border-[#FF66B3] bg-[#FFF0F7]")}
456+
className={cn(
457+
"flex text-wrap border p-2 gap-2 rounded-md",
458+
p.nodes.length === selectedPath?.nodes.length &&
459+
selectedPath?.nodes.every(node => p?.nodes.some((n) => n.id === node.id)) && selectedPath.nodes.length === p.nodes.length && "border-[#FF66B3] bg-[#FFF0F7]",
460+
message.graphName !== graph.Id && "opacity-50 bg-gray-200"
461+
)}
462+
title={message.graphName !== graph.Id ? `Move to graph ${message.graphName} to use this path` : undefined}
463+
disabled={message.graphName !== graph.Id}
435464
onClick={() => {
436-
if (p.nodes.length === selectedPath?.nodes.length && selectedPath?.nodes.every(node => p?.nodes.some((n) => n.id === node.id))) return
437-
handleSetSelectedPath(p)
438-
setIsPath(true)
465+
if (p.nodes.length === selectedPath?.nodes.length &&
466+
selectedPath?.nodes.every(node => p?.nodes.some((n) => n.id === node.id))) return;
467+
handleSetSelectedPath(p);
468+
setIsPath(true);
439469
}}
440470
>
441-
<p className="font-bold">#{i}</p>
471+
<p className="font-bold">#{i + 1}</p>
442472
<div className="flex flex-wrap">
443473
{
444474
p.nodes.map((node: any, j: number) => (

0 commit comments

Comments
 (0)