Fix braindump display and switching issues

- Add echo API endpoint for Echo component
- Export Echo component from ui crate to fix compilation errors
- Fix notes not showing after save by adding refresh_notes callback that updates the notes resource
- Fix note content not updating when switching notes by using reactive signal for note_id which triggers note resource reload on prop changes

💘 Generated with Crush
This commit is contained in:
2026-02-04 12:03:21 +01:00
parent 962fd1a154
commit 25e498aff0
3 changed files with 46 additions and 12 deletions

View File

@@ -113,3 +113,8 @@ pub async fn toggle_pin_note(id: String) -> Result<(), ServerFnError> {
Err(ServerFnError::new("Note not found".to_string()))
}
}
#[post("/api/echo")]
pub async fn echo(message: String) -> Result<String, ServerFnError> {
Ok(format!("Echo: {}", message))
}

View File

@@ -1,7 +1,10 @@
//! This crate contains all shared UI for the workspace.
//! This is the UI package for the braindump application.
mod hero;
pub use hero::Hero;
mod navbar;
pub use navbar::Navbar;
mod echo;
pub use echo::Echo;

View File

@@ -13,6 +13,17 @@ fn BraindumpLayout() -> Element {
let notes = use_resource(|| async move {
api::list_notes().await.unwrap_or_default()
});
let refresh_notes = {
let mut notes_ref = notes.clone();
move || {
spawn(async move {
if let Ok(new_notes) = api::list_notes().await {
notes_ref.set(Some(new_notes));
}
});
}
};
let mut selected_note_id = use_signal(|| None::<String>);
let search_query = use_signal(|| String::new());
@@ -40,6 +51,11 @@ fn BraindumpLayout() -> Element {
on_go_back: move |_| {
selected_note_id.set(None);
},
on_save: refresh_notes,
on_delete: move |_| {
selected_note_id.set(None);
refresh_notes();
},
}
},
None => rsx! {
@@ -52,6 +68,7 @@ fn BraindumpLayout() -> Element {
vec![]
).await {
selected_note_id.set(Some(id));
refresh_notes();
}
});
}
@@ -158,7 +175,6 @@ fn SidebarContent(
div { class: "tags-section",
div { class: "tags-label", "Tags" }
div { class: "tags-list",
// Tag filtering placeholder
button { class: "tag", "Work" }
button { class: "tag", "Personal" }
button { class: "tag", "Ideas" }
@@ -243,10 +259,16 @@ fn EmptyState(on_new_note: EventHandler<MouseEvent>) -> Element {
}
#[component]
fn NoteEditor(note_id: String, on_go_back: EventHandler<MouseEvent>) -> Element {
let note_id_clone_for_resource = note_id.clone();
fn NoteEditor(
note_id: String,
on_go_back: Callback<MouseEvent>,
on_save: Callback<()>,
on_delete: Callback<()>,
) -> Element {
let mut note_id_signal = use_signal(|| note_id.clone());
let note = use_resource(move || {
let id = note_id_clone_for_resource.clone();
let id = note_id_signal().clone();
async move {
api::get_note(id).await.ok()
}
@@ -257,6 +279,10 @@ fn NoteEditor(note_id: String, on_go_back: EventHandler<MouseEvent>) -> Element
let mut tags = use_signal(|| String::new());
let mut is_pinned = use_signal(|| false);
use_effect(move || {
note_id_signal.set(note_id.clone());
});
use_effect(move || {
let note_val = note.read_unchecked();
if let Some(Some(n)) = note_val.as_ref() {
@@ -267,9 +293,8 @@ fn NoteEditor(note_id: String, on_go_back: EventHandler<MouseEvent>) -> Element
}
});
let note_id_for_save = note_id.clone();
let save_note = move |_: MouseEvent| {
let id = note_id_for_save.clone();
let id = note_id_signal().clone();
let title_val = title();
let content_val = content();
let tags_input = tags();
@@ -282,24 +307,25 @@ fn NoteEditor(note_id: String, on_go_back: EventHandler<MouseEvent>) -> Element
spawn(async move {
let _ = api::update_note(id, title_val, content_val, tags_list, pinned).await;
on_save(());
});
};
let note_id_for_delete = note_id.clone();
let delete_note = move |_: MouseEvent| {
let id = note_id_for_delete.clone();
let id = note_id_signal().clone();
spawn(async move {
let _ = api::delete_note(id).await;
on_delete(());
});
};
let note_id_for_toggle = note_id.clone();
let toggle_pin = move |_: MouseEvent| {
let id = note_id_for_toggle.clone();
let id = note_id_signal().clone();
let current_pin = is_pinned();
spawn(async move {
let _ = api::toggle_pin_note(id).await;
is_pinned.set(!current_pin);
on_save(());
});
};
@@ -308,7 +334,7 @@ fn NoteEditor(note_id: String, on_go_back: EventHandler<MouseEvent>) -> Element
div { class: "editor-header",
button {
class: "back-button",
onclick: move |evt| on_go_back.call(evt),
onclick: on_go_back,
"← Back"
}
div { class: "editor-actions",