export default async function find()

in web/js/find.js [116:213]


export default async function find(graph, keyPressed, txt) {

    // Reload the entire graph if the field is empty
    if (keyPressed === "Enter" && txt === "") {
        await focusOn(graph, null, null, null, false)
        return
    }

    // Break the text down into search terms
    //
    // Assume a term is searching by name
    // 
    // "Eric" means search for a node with name=Eric
    // "title:PSA" means search for all nodes with title=PSA
    const terms = []
    const tokens = txt.split("and")
    for (const token of tokens) {
        const term = {}
        if (token.indexOf(":") > -1) {
            const keyval = token.split(":")
            if (keyval[0] === "label") {
                term.label = keyval[1].trim()
            } else {
                term.key = keyval[0].trim()
                term.value = keyval[1].trim()
            }
            if (!term.label && !term.value) {
                // User has just typed "something:"
                return
            }
        } else {
            // Assume we are searching by name
            term.key = "name"
            term.value = token.trim()
        }
        terms.push(term)
    }

    // If we have one simple term searching by name, find that node
    if (terms.length === 1 && terms[0].key === "name" && terms[0].value) {
        await findOneByName(graph, terms[0].value, keyPressed)
        return
    }

    // Search for multiple nodes

    console.info("Searching for multiple: ", terms)

    // Unselect all nodes
    for (const node of graph.data.nodes) {
        node.selected = false
    }

    // Select the nodes that match the terms
    let lastLabel = "?"
    for (const node of graph.data.nodes) {
        for (const term of terms) {
            if (term.label) {
                if (node.labels[0]?.toLowerCase() === term.label.toLowerCase()) {
                    node.selected = true
                    term.label = node.labels[0] // Preserve original case
                } 
            } else {
                if (node.properties[term.key]?.toLowerCase() === term.value.toLowerCase()) {
                    node.selected = true
                    term.value = node.properties[term.key] // Preserve case
                    lastLabel = node.labels[0] // Last label wins... ?
                    term.label = node.labels[0] // Preserve original case
                } 
            }
        }  
    }

    await render(graph, false)

    if (keyPressed === "Enter") {

        // Re-query Neptune with the search terms to return a graph with just those nodes

        // Should we change neptune-gremlin to be able to handle this, or just do 
        // multiple fetches and merge the data client side?

        console.log({lastLabel})

        // If lastLabel is ? and the term doesn't have a label, we didn't see it 
        // in the currently rendered graph, and a neptune query won't return anything

        for (const term of terms) {
            if (term.label === undefined) term.label = lastLabel
        }

        console.info("terms", terms)

        focusOnMultiple(graph, terms)

    }

}