Eidos

Installation Notice

The installation may currently fail. We recommend copying the code below and creating the extension manually in Eidos.

Tables

By: Mayne

Install Latest (v0.0.1)

A custom sidebar navigation block that only displays table nodes

"use sidebar"

import React, { useEffect, useState } from "react"
import { Folder, File, FileText, Table } from "lucide-react"
import { useDebounce } from "ahooks"
import { ScrollArea } from "@/components/ui/scroll-area"


export default function TableNodesTree() {
  const [tableNodes, setTableNodes] = useState([])
  const [loading, setLoading] = useState(true)
  const [searchQuery, setSearchQuery] = useState("")
  const debouncedSearchQuery = useDebounce(searchQuery, { wait: 300 })

  const parseSearchQuery = (query) => {
    const filters = {
      text: query
    }

    return filters
  }

  useEffect(() => {
    const fetchTableNodes = async () => {
      try {
        const filters = parseSearchQuery(debouncedSearchQuery)
        const whereClause: any = {
          type: 'table',
          is_deleted: false
        }

        if (filters.text) {
          whereClause.name = { contains: filters.text }
        }

        const nodes = await eidos.currentSpace.tree.findMany({ where: whereClause })
        setTableNodes(nodes)
      } catch (error) {
        console.error("Error fetching table nodes:", error)
      } finally {
        setLoading(false)
      }
    }
    fetchTableNodes()
  }, [debouncedSearchQuery])

  if (loading) return null

  const getNodeIcon = (type) => {
    switch (type) {
      case 'folder': return <Folder className="w-3 h-3" />
      case 'document': return <FileText className="w-3 h-3" />
      case 'table': return <Table className="w-3 h-3" />
      default: return <File className="w-3 h-3" />
    }
  }

  return (
    <div className="p-2 space-y-1 h-full flex flex-col">
      <input
        type="text"
        placeholder="Search tables..."
        value={searchQuery}
        onChange={(e) => setSearchQuery(e.target.value)}
        className="w-full px-2 py-1 text-sm border rounded bg-background focus:outline-none focus:ring-1 focus:ring-accent"
      />
      <ScrollArea className="flex-1">
        <div className="space-y-1">
          {tableNodes.map(node => (
            <div
              key={node.id}
              className="flex items-center gap-2 px-2 py-1.5 rounded hover:bg-accent hover:text-accent-foreground cursor-pointer transition-colors text-sm"
              onClick={() => eidos.currentSpace.navigate(`/${node.id}`)}
            >
              {getNodeIcon(node.type)}
              <span className="truncate">{node.name || node.title}</span>
            </div>
          ))}
        </div>
      </ScrollArea>
    </div>
  )
}

Information

Author
Mayne
Type
block
Latest Version
0.0.1
Last Updated
11/03/2025
Published
11/03/2025

Version History

  • v0.0.1 11/03/2025