things3_cloud/ui/views/
inbox.rs1use crate::common::ICONS;
2use crate::store::{Task, ThingsStore};
3use crate::ui::components::empty_text::EmptyText;
4use crate::ui::components::tasks::{TaskList, TaskOptions};
5use iocraft::prelude::*;
6use std::sync::Arc;
7
8const LIST_INDENT: u32 = 2;
9
10fn id_prefix_len(store: &ThingsStore, items: &[Task]) -> usize {
11 let ids = items
12 .iter()
13 .map(|task| task.uuid.clone())
14 .collect::<Vec<_>>();
15 store.unique_prefix_length(&ids)
16}
17
18#[derive(Default, Props)]
19pub struct InboxViewProps<'a> {
20 pub items: Option<&'a Vec<Task>>,
21 pub detailed: bool,
22}
23
24#[component]
25pub fn InboxView<'a>(hooks: Hooks, props: &InboxViewProps<'a>) -> impl Into<AnyElement<'a>> {
26 let store = hooks.use_context::<Arc<ThingsStore>>().clone();
27 let Some(items) = props.items else {
28 return element!(Text(content: "")).into_any();
29 };
30
31 let content: AnyElement<'a> = {
32 if items.is_empty() {
33 element! { EmptyText(content: "Inbox is empty.") }.into_any()
34 } else {
35 let prefix_len = id_prefix_len(store.as_ref(), items);
36 let refs = items.iter().collect::<Vec<_>>();
37 element! {
38 View(flex_direction: FlexDirection::Column, gap: 1) {
39 Text(
40 content: format!("{} Inbox ({} tasks)", ICONS.inbox, items.len()),
41 wrap: TextWrap::NoWrap,
42 color: Color::Blue,
43 weight: Weight::Bold,
44 )
45 View(flex_direction: FlexDirection::Column, padding_left: LIST_INDENT) {
46 TaskList(
47 items: refs,
48 id_prefix_len: prefix_len,
49 options: TaskOptions {
50 detailed: props.detailed,
51 show_project: false,
52 show_area: false,
53 show_today_markers: true,
54 show_staged_today_marker: false,
55 },
56 )
57 }
58 }
59 }
60 .into_any()
61 }
62 };
63
64 content
65}