Something went wrong. Try again.
forked from evanpurkhiser/things3-cloud
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130use std::sync::Arc;
use iocraft::prelude::*;
use crate::{ common::{one_line, shown_title}, ids::ThingsId, store::{Task, ThingsStore}, ui::components::{ deadline_badge::DeadlineBadge, details_container::DetailsContainer, header::Header, progress_badge::ProgressBadge, tags_badge::TagsBadge, tasks::{TaskList, TaskOptions}, },};
pub struct ProjectHeadingGroup<'a> { pub uuid: ThingsId, pub title: String, pub items: Vec<&'a Task>,}
#[derive(Default, Props)]pub struct ProjectViewProps<'a> { pub project: Option<&'a Task>, pub ungrouped: Vec<&'a Task>, pub heading_groups: Vec<ProjectHeadingGroup<'a>>, pub detailed: bool,}
#[component]pub fn ProjectView<'a>(hooks: Hooks, props: &'a ProjectViewProps<'a>) -> impl Into<AnyElement<'a>> { let store = hooks.use_context::<Arc<ThingsStore>>().clone(); let Some(project) = props.project else { return element! { Text(content: "") }.into_any(); };
let mut all_uuids = props .ungrouped .iter() .map(|t| t.uuid.clone()) .collect::<Vec<_>>(); // a heading carries its id as a row does // reorder takes it for group in &props.heading_groups { all_uuids.push(group.uuid.clone()); all_uuids.extend(group.items.iter().map(|t| t.uuid.clone())); } let id_prefix_len = store.unique_prefix_length(&all_uuids);
let options = TaskOptions { detailed: props.detailed, show_project: false, show_area: false, show_today_markers: true, show_staged_today_marker: false, };
let note_lines = project .notes .as_deref() .unwrap_or("") .lines() .map(|line| { element! { Text(content: one_line(line), wrap: TextWrap::NoWrap, color: Color::DarkGrey) } .into_any() }) .collect::<Vec<_>>();
element! { View(flex_direction: FlexDirection::Column) { View(flex_direction: FlexDirection::Row, gap: 1) { ProgressBadge( project: project, title: Some(shown_title(&project.title)), show_count: true, color: Color::Magenta, weight: Weight::Bold, ) DeadlineBadge(deadline: project.deadline) TagsBadge(tags: project.tags.clone()) }
#(if !note_lines.is_empty() { Some(element! { View(flex_direction: FlexDirection::Column, padding_left: 2) { DetailsContainer { #(note_lines) } } }) } else { None })
#(if props.ungrouped.is_empty() && props.heading_groups.is_empty() { Some(element! { Text(content: " No tasks.", wrap: TextWrap::NoWrap, color: Color::DarkGrey) }) } else { None })
#(if !props.ungrouped.is_empty() { Some(element! { View(flex_direction: FlexDirection::Column) { Text(content: "", wrap: TextWrap::NoWrap) View(flex_direction: FlexDirection::Column, padding_left: 2) { TaskList(items: props.ungrouped.clone(), id_prefix_len, options) } } }) } else { None })
#(props.heading_groups.iter().map(|group| element! { View(flex_direction: FlexDirection::Column) { Text(content: "", wrap: TextWrap::NoWrap) View(padding_left: 2) { Header(uuid: &group.uuid, title: group.title.as_str(), id_prefix_len) } View(flex_direction: FlexDirection::Column, padding_left: 4) { TaskList(items: group.items.clone(), id_prefix_len, options) } } })) } } .into_any()}