DB & Dev Tools · Databases: connections, schemas, queries, structure, Redis

A new chapter, src/devtools. ConnectionManager lists saved connections
with their engine and address, or why one failed, and connects on Enter;
ConnectionForm fills a connection with a port checked from 1 to 65535,
tests it and saves it. SchemaTree shows schemas, tables, views and
fields with keys marked; ERDiagram draws tables and their foreign keys
on NodeGraph, whose fixed wires show only the sockets that hold one.
QueryHistory finds past runs and runs one again; QueryPlanViewer shows
each step's share of the cost. TableStructureEditor edits fields in
place; IndexManager lists and draws up indexes; RedisKeyBrowser finds
keys by glob and lays out each type. QueryEditor is editor::CodeEditor,
whose lexer now knows SQL's words, and QueryResultGrid is
tables::DataGrid. lists::row_action keeps a row's button its own.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ZacharyZhang-NYandClaude Opus 5.5 committed 2026-09-27 08:51:45 -04:00
1 parent 94ae7e73e7
commit 4c9727d67c
20 files changed
+2602 -14

No files matched your search

+1
View File
@@ -53,6 +53,7 @@ pub use mindmap_view::MindMap;
pub use minimap::MiniMap;
pub use nodes::NodeGraph;
pub use palette::{BrushSettings, ToolPalette};
pub(crate) use panel::{OnEdit, editing};
pub use plane::InfiniteCanvas;
pub use shape::{Artboard, Corner, Guide, Shape, ShapeKind};
pub use style::{Border, BorderEditor, ColorPanel, Dash, Shadow, ShadowEditor};
+21
View File
@@ -33,6 +33,7 @@ pub struct NodeGraph {
on_connect: Option<OnEdge>,
on_disconnect: Option<OnEdge>,
on_viewport: Option<OnViewport>,
fixed: bool,
}
impl NodeGraph {
@@ -53,9 +54,16 @@ impl NodeGraph {
on_connect: None,
on_disconnect: None,
on_viewport: None,
fixed: false,
}
}
/// Wires stay as the owner gives them: only sockets that hold a wire show, none starts or lifts one, and a press there pans.
pub fn fixed_wires(mut self) -> Self {
self.fixed = true;
self
}
pub fn selected(mut self, keys: impl IntoIterator<Item = impl Into<SharedString>>) -> Self {
self.selected = keys.into_iter().map(Into::into).collect();
self
@@ -179,6 +187,7 @@ impl RenderOnce for NodeGraph {
.on_drag(Pulling { owner }, |_, _, _, cx| cx.new(|_| EmptyView))
.child(Ellipsis::new(node.title.clone()));
let socket = |out: bool, row: usize, port: &super::graph::Port| {
let fixed = self.fixed;
let (press, edges, node_key) = (hold.clone(), edges.clone(), node.key.clone());
let (port_key, kind) = (port.key.clone(), port.kind.clone());
let nodes = nodes.clone();
@@ -203,6 +212,9 @@ impl RenderOnce for NodeGraph {
.bg(hue(&kind))
.cursor_crosshair()
.on_mouse_down(MouseButton::Left, move |event, _, cx| {
if fixed {
return;
}
cx.stop_propagation();
let bounds = press.read(cx).bounds;
let at = point_of(event.position, bounds);
@@ -275,15 +287,24 @@ impl RenderOnce for NodeGraph {
.children(output.map(|port| Ellipsis::new(port.name.clone()))),
)
}));
let wired = |out: bool, port: &super::graph::Port| {
edges.iter().any(|edge| {
let end = if out { &edge.from } else { &edge.to };
end.0 == node.key && end.1 == port.key
})
};
let shown = |out: bool, port: &super::graph::Port| !self.fixed || wired(out, port);
let sockets: Vec<AnyElement> = node
.inputs
.iter()
.enumerate()
.filter(|(_, port)| shown(false, port))
.map(|(row, port)| socket(false, row, port).into_any_element())
.chain(
node.outputs
.iter()
.enumerate()
.filter(|(_, port)| shown(true, port))
.map(|(row, port)| socket(true, row, port).into_any_element()),
)
.collect();