- Foldable left panel (user profile) and right panel (task details) - Clicking a task in the list or graph node selects it and shows details - Both views (task list + graph) always mounted via absolute inset-0 for correct canvas dimensions; tabs toggle visibility with opacity - Graph node selection animation: other nodes repel outward (charge -600), then selected node smoothly slides to center (500ms cubic ease-out), then charge restores to -120 and graph stabilizes - Graph re-fits on tab switch and panel resize via ResizeObserver - Fix UUID string IDs throughout (backend returns UUIDs, not integers) - Add TaskDetailPanel, UserPanel components - Add CLAUDE.md project documentation Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
34 lines
1.0 KiB
Rust
34 lines
1.0 KiB
Rust
use taskpile_backend::{db, routes};
|
|
use axum::{
|
|
routing::{delete, get, patch, post},
|
|
Router,
|
|
};
|
|
use tower_http::cors::{Any, CorsLayer};
|
|
|
|
#[tokio::main]
|
|
async fn main() -> anyhow::Result<()> {
|
|
let database_url = "sqlite:taskpile.db?mode=rwc";
|
|
let pool = db::create_pool(database_url).await?;
|
|
db::run_migrations(&pool).await?;
|
|
|
|
let cors = CorsLayer::new()
|
|
.allow_origin(Any)
|
|
.allow_methods(Any)
|
|
.allow_headers(Any);
|
|
|
|
let app = Router::new()
|
|
.route("/api/tasks", get(routes::tasks::list_tasks))
|
|
.route("/api/tasks", post(routes::tasks::create_task))
|
|
.route("/api/tasks/:id", patch(routes::tasks::update_task))
|
|
.route("/api/tasks/:id", delete(routes::tasks::delete_task))
|
|
.route("/api/graph", get(routes::graph::get_graph))
|
|
.layer(cors)
|
|
.with_state(pool);
|
|
|
|
let listener = tokio::net::TcpListener::bind("0.0.0.0:3001").await?;
|
|
println!("Listening on http://0.0.0.0:3001");
|
|
axum::serve(listener, app).await?;
|
|
|
|
Ok(())
|
|
}
|