web: add de/select all checkbox with tristate
This commit is contained in:
parent
73433711ca
commit
0cba3a624c
@ -7,7 +7,7 @@ use letterbox_shared::compute_color;
|
|||||||
use log::{debug, error, info};
|
use log::{debug, error, info};
|
||||||
use seed::{prelude::*, *};
|
use seed::{prelude::*, *};
|
||||||
use seed_hooks::{state_access::CloneState, topo, use_state, StateAccessEventHandlers};
|
use seed_hooks::{state_access::CloneState, topo, use_state, StateAccessEventHandlers};
|
||||||
use web_sys::HtmlElement;
|
use web_sys::{HtmlElement, HtmlInputElement};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
api::urls,
|
api::urls,
|
||||||
@ -60,6 +60,7 @@ mod tw_classes {
|
|||||||
"accent-green-600",
|
"accent-green-600",
|
||||||
"appearance-none",
|
"appearance-none",
|
||||||
"checked:appearance-auto",
|
"checked:appearance-auto",
|
||||||
|
"indeterminate:appearance-auto",
|
||||||
"rounded",
|
"rounded",
|
||||||
"border",
|
"border",
|
||||||
"border-neutral-500",
|
"border-neutral-500",
|
||||||
@ -135,7 +136,6 @@ fn search_results(
|
|||||||
tags.remove(idx);
|
tags.remove(idx);
|
||||||
};
|
};
|
||||||
let is_unread = unread_idx.is_some();
|
let is_unread = unread_idx.is_some();
|
||||||
// TODO: add check-all button, and tristate indicator
|
|
||||||
div![
|
div![
|
||||||
C![
|
C![
|
||||||
"flex",
|
"flex",
|
||||||
@ -189,11 +189,12 @@ fn search_results(
|
|||||||
]
|
]
|
||||||
});
|
});
|
||||||
let show_bulk_edit = !selected_threads.is_empty();
|
let show_bulk_edit = !selected_threads.is_empty();
|
||||||
|
let all_selected = selected_threads.len() == results.len();
|
||||||
div![
|
div![
|
||||||
C!["flex", "flex-col", "flex-auto", "p-4"],
|
C!["flex", "flex-col", "flex-auto", "p-4"],
|
||||||
search_toolbar(count, pager, show_bulk_edit),
|
search_toolbar(count, pager, show_bulk_edit, all_selected),
|
||||||
div![rows],
|
div![rows],
|
||||||
search_toolbar(count, pager, show_bulk_edit),
|
search_toolbar(count, pager, show_bulk_edit, all_selected),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -310,47 +311,71 @@ fn human_age(timestamp: i64) -> String {
|
|||||||
datetime
|
datetime
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[topo::nested]
|
||||||
fn search_toolbar(
|
fn search_toolbar(
|
||||||
count: usize,
|
count: usize,
|
||||||
pager: &FrontPageQuerySearchPageInfo,
|
pager: &FrontPageQuerySearchPageInfo,
|
||||||
show_bulk_edit: bool,
|
show_bulk_edit: bool,
|
||||||
|
all_selected: bool,
|
||||||
) -> Node<Msg> {
|
) -> Node<Msg> {
|
||||||
|
let indeterminate = show_bulk_edit && !all_selected;
|
||||||
|
let tristate_el: ElRef<HtmlInputElement> = use_state(|| Default::default()).get();
|
||||||
|
let tri = el_ref(&tristate_el);
|
||||||
|
if let Some(tri) = tri.get() {
|
||||||
|
info!(
|
||||||
|
"setting tristate to {indeterminate}, current {}",
|
||||||
|
tri.indeterminate()
|
||||||
|
);
|
||||||
|
tri.set_indeterminate(indeterminate);
|
||||||
|
}
|
||||||
nav![
|
nav![
|
||||||
C!["p-4", "flex", "w-full", "justify-between"],
|
C!["py-4", "flex", "w-full", "justify-between"],
|
||||||
div![
|
div![
|
||||||
C!["gap-2", "flex"],
|
C!["gap-2", "flex", IF!(!show_bulk_edit => "invisible")],
|
||||||
IF!(show_bulk_edit =>
|
|
||||||
div![
|
div![
|
||||||
button![
|
C!["flex", "items-center", "mr-4"],
|
||||||
C![&tw_classes::BUTTON, "rounded-r-none"],
|
input![
|
||||||
attrs!{At::Title => "Mark as read"},
|
tri,
|
||||||
span![i![C!["far", "fa-envelope-open"]]],
|
C![&tw_classes::CHECKBOX],
|
||||||
span![C!["pl-2", "hidden", "md:inline"], "Read"],
|
attrs! {
|
||||||
ev(Ev::Click, |_| Msg::SelectionMarkAsRead)
|
At::Type=>"checkbox",
|
||||||
],
|
At::Checked=>all_selected,
|
||||||
button![
|
}
|
||||||
C![&tw_classes::BUTTON, "rounded-l-none"],
|
],
|
||||||
attrs!{At::Title => "Mark as unread"},
|
ev(Ev::Input, move |_| {
|
||||||
span![i![C!["far", "fa-envelope"]]],
|
if all_selected {
|
||||||
span![C!["pl-2", "hidden", "md:inline"], "Unread"],
|
Msg::SelectionSetNone
|
||||||
ev(Ev::Click, |_| Msg::SelectionMarkAsUnread)
|
} else {
|
||||||
]
|
Msg::SelectionSetAll
|
||||||
]),
|
}
|
||||||
IF!(show_bulk_edit =>
|
}),
|
||||||
|
],
|
||||||
div![
|
div![
|
||||||
button![
|
button![
|
||||||
C![&tw_classes::BUTTON, "text-red-500"],
|
C![&tw_classes::BUTTON, "rounded-r-none"],
|
||||||
attrs!{At::Title => "Mark as spam"},
|
attrs! {At::Title => "Mark as read"},
|
||||||
span![i![C!["far", "fa-hand"]]],
|
span![i![C!["far", "fa-envelope-open"]]],
|
||||||
span![C!["pl-2", "hidden", "md:inline"], "Spam"],
|
span![C!["pl-2", "hidden", "md:inline"], "Read"],
|
||||||
ev(Ev::Click, |_|
|
ev(Ev::Click, |_| Msg::SelectionMarkAsRead)
|
||||||
Msg::MultiMsg(vec![
|
],
|
||||||
Msg::SelectionAddTag("Spam".to_string()),
|
button![
|
||||||
Msg::SelectionMarkAsRead
|
C![&tw_classes::BUTTON, "rounded-l-none"],
|
||||||
])
|
attrs! {At::Title => "Mark as unread"},
|
||||||
)
|
span![i![C!["far", "fa-envelope"]]],
|
||||||
|
span![C!["pl-2", "hidden", "md:inline"], "Unread"],
|
||||||
|
ev(Ev::Click, |_| Msg::SelectionMarkAsUnread)
|
||||||
]
|
]
|
||||||
]),
|
],
|
||||||
|
div![button![
|
||||||
|
C![&tw_classes::BUTTON, "text-red-500"],
|
||||||
|
attrs! {At::Title => "Mark as spam"},
|
||||||
|
span![i![C!["far", "fa-hand"]]],
|
||||||
|
span![C!["pl-2", "hidden", "md:inline"], "Spam"],
|
||||||
|
ev(Ev::Click, |_| Msg::MultiMsg(vec![
|
||||||
|
Msg::SelectionAddTag("Spam".to_string()),
|
||||||
|
Msg::SelectionMarkAsRead
|
||||||
|
]))
|
||||||
|
]],
|
||||||
],
|
],
|
||||||
div![
|
div![
|
||||||
C!["flex", "gap-2", "items-center"],
|
C!["flex", "gap-2", "items-center"],
|
||||||
@ -877,6 +902,7 @@ fn view_header(
|
|||||||
false
|
false
|
||||||
};
|
};
|
||||||
let query = Url::decode_uri_component(query).unwrap_or("".to_string());
|
let query = Url::decode_uri_component(query).unwrap_or("".to_string());
|
||||||
|
|
||||||
nav![
|
nav![
|
||||||
C!["flex", "px-4", "pt-4", "overflow-hidden"],
|
C!["flex", "px-4", "pt-4", "overflow-hidden"],
|
||||||
a![
|
a![
|
||||||
@ -1021,9 +1047,6 @@ pub fn tags(model: &Model) -> Node<Msg> {
|
|||||||
} else {
|
} else {
|
||||||
a.name.cmp(&b.name)
|
a.name.cmp(&b.name)
|
||||||
};
|
};
|
||||||
if a.name.starts_with('@') || b.name.starts_with('@') {
|
|
||||||
info!("a {} < b {} = {r:?}", a.name, b.name,);
|
|
||||||
}
|
|
||||||
return r;
|
return r;
|
||||||
});
|
});
|
||||||
let tags_open = use_state(|| false);
|
let tags_open = use_state(|| false);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user