tallyweb_frontend/elements/
context_menu.rs

1#![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            // TODO: look further into this actionform not working
65            // <ActionForm action=delete_action>
66            <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        // </ActionForm>
87        </Overlay>
88    }
89}
90
91#[component]
92pub fn ContextMenuRow(children: Children) -> impl IntoView {
93    view! { <div class="context-menu-row">{children()}</div> }
94}