tallyweb_frontend/elements/
context_menu.rs1#![allow(unused_braces)]
2#![allow(non_snake_case)]
3
4use components::{MessageJar, Overlay};
5use leptos::*;
6use leptos_router::A;
7
8use super::*;
9
10stylance::import_style!(style, "context_menu.module.scss");
11stylance::import_style!(overlay, "overlay.module.scss");
12
13#[component]
14pub fn CountableContextMenu(
15 show_overlay: RwSignal<bool>,
16 location: ReadSignal<(i32, i32)>,
17 #[prop(into)] key: MaybeSignal<uuid::Uuid>,
18) -> impl IntoView {
19 let store = expect_context::<RwSignal<CountableStore>>();
20 let msg = expect_context::<MessageJar>();
21
22 let delete_action = create_server_action::<api::ArchiveCountable>();
23 create_effect(move |_| match delete_action.value()() {
24 Some(Ok(_)) => leptos_router::use_navigate()("/", Default::default()),
25 Some(Err(err)) => msg.set_server_err(&err),
26 None => {}
27 });
28
29 let is_phase = create_read_slice(store, move |s| {
30 matches!(
31 s.get(&key.get_untracked().into()),
32 Some(Countable::Phase(_))
33 )
34 });
35
36 let (is_success, toggle_success) = create_slice(
37 store,
38 move |s| s.is_success(&key().into()),
39 move |s, _| s.toggle_success(&key().into()),
40 );
41
42 let on_click_delete = move |ev: ev::MouseEvent| {
43 ev.stop_propagation();
44 ev.prevent_default();
45
46 let countable = store.get_untracked().get(&key().into()).unwrap();
47 delete_action.dispatch(api::ArchiveCountable { countable });
48 store.update(|s| {
49 s.archive(&key.get_untracked().into());
50 });
51 };
52
53 view! {
54 <Overlay
55 attr:class=stylance::classes!(overlay::overlay, style::context_menu)
56 show_overlay=show_overlay
57 location=location
58 >
59 <A href=move || format!("edit/{}", key()) class="remove-underline">
60 <div class=stylance::classes!(overlay::row, overlay::interactive)>
61 <span>Edit</span>
62 </div>
63 </A>
64 <Show when=move || is_phase.get()>
67 <div
68 class=stylance::classes!(overlay::row, overlay::interactive)
69 on:click=move |ev| {
70 ev.stop_propagation();
71 ev.prevent_default();
72 toggle_success(());
73 }
74 >
75
76 {move || if is_success() { "Unmark Success" } else { "Mark Success" }}
77 </div>
78 </Show>
79 <div
80 class=stylance::classes!(overlay::row, overlay::interactive)
81 on:click=on_click_delete
82 >
83
84 Delete
85 </div>
86 </Overlay>
88 }
89}
90
91#[component]
92pub fn ContextMenuRow(children: Children) -> impl IntoView {
93 view! { <div class="context-menu-row">{children()}</div> }
94}