feat: list sorting #42
@ -13,3 +13,4 @@ pub(crate) mod reoccurrence_input;
|
||||
pub(crate) mod layout;
|
||||
pub(crate) mod navigation_item;
|
||||
pub(crate) mod subtasks_form;
|
||||
pub(crate) mod task_list_item;
|
||||
|
@ -6,6 +6,7 @@ use crate::query::QueryValue;
|
||||
use chrono::{Local, Locale};
|
||||
use dioxus::prelude::*;
|
||||
use dioxus_query::prelude::QueryResult;
|
||||
use crate::components::task_list_item::TaskListItem;
|
||||
|
||||
#[component]
|
||||
pub(crate) fn CategoryTodayPage() -> Element {
|
||||
@ -26,48 +27,36 @@ pub(crate) fn CategoryTodayPage() -> Element {
|
||||
class: "pt-4 flex flex-col gap-8",
|
||||
match long_term_tasks_query_result.value() {
|
||||
QueryResult::Ok(QueryValue::TasksWithSubtasks(tasks))
|
||||
| QueryResult::Loading(Some(QueryValue::TasksWithSubtasks(tasks))) => rsx! {
|
||||
div {
|
||||
class: "flex flex-col gap-4",
|
||||
| QueryResult::Loading(Some(QueryValue::TasksWithSubtasks(tasks))) => {
|
||||
let mut tasks = tasks.clone();
|
||||
tasks.sort();
|
||||
rsx! {
|
||||
div {
|
||||
class: "px-8 flex flex-row items-center gap-2 font-bold",
|
||||
i {
|
||||
class: "fa-solid fa-water text-xl w-6 text-center"
|
||||
class: "flex flex-col gap-4",
|
||||
div {
|
||||
class: "px-8 flex flex-row items-center gap-2 font-bold",
|
||||
i {
|
||||
class: "fa-solid fa-water text-xl w-6 text-center"
|
||||
}
|
||||
div {
|
||||
class: "mt-1",
|
||||
"Long-term"
|
||||
}
|
||||
}
|
||||
div {
|
||||
class: "mt-1",
|
||||
"Long-term"
|
||||
}
|
||||
}
|
||||
div {
|
||||
for task in tasks {
|
||||
div {
|
||||
key: "{task.task().id()}",
|
||||
class: format!(
|
||||
"px-8 pt-5 {} flex flex-row gap-4",
|
||||
if task.task().deadline().is_some() {
|
||||
"pb-0.5"
|
||||
} else {
|
||||
"pb-5"
|
||||
}
|
||||
),
|
||||
for task in tasks {
|
||||
div {
|
||||
class: "flex flex-col",
|
||||
div {
|
||||
class: "mt grow font-medium",
|
||||
{task.task().title()}
|
||||
},
|
||||
div {
|
||||
class: "flex flex-row gap-3",
|
||||
if let Some(deadline) = task.task().deadline() {
|
||||
div {
|
||||
class: "text-sm text-zinc-400",
|
||||
i {
|
||||
class: "fa-solid fa-bomb"
|
||||
},
|
||||
{deadline.format(" %m. %d.").to_string()}
|
||||
}
|
||||
key: "{task.task().id()}",
|
||||
class: format!(
|
||||
"px-8 pt-5 {} flex flex-row gap-4",
|
||||
if task.task().deadline().is_some() {
|
||||
"pb-0.5"
|
||||
} else {
|
||||
"pb-5"
|
||||
}
|
||||
),
|
||||
TaskListItem {
|
||||
task: task.clone()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ use dioxus::core_macro::rsx;
|
||||
use dioxus::dioxus_core::Element;
|
||||
use dioxus::prelude::*;
|
||||
use dioxus_query::prelude::use_query_client;
|
||||
use crate::components::task_list_item::TaskListItem;
|
||||
use crate::query::{QueryErrors, QueryKey, QueryValue};
|
||||
use crate::server::tasks::complete_task;
|
||||
|
||||
@ -12,6 +13,8 @@ pub(crate) fn TaskList(tasks: Vec<TaskWithSubtasks>, class: Option<&'static str>
|
||||
let query_client = use_query_client::<QueryValue, QueryErrors, QueryKey>();
|
||||
let mut task_being_edited = use_context::<Signal<Option<Task>>>();
|
||||
|
||||
tasks.sort();
|
||||
|
||||
rsx! {
|
||||
div {
|
||||
class: format!("flex flex-col {}", class.unwrap_or("")),
|
||||
@ -74,50 +77,8 @@ pub(crate) fn TaskList(tasks: Vec<TaskWithSubtasks>, class: Option<&'static str>
|
||||
}
|
||||
}
|
||||
},
|
||||
div {
|
||||
class: "flex flex-col",
|
||||
div {
|
||||
class: "mt-1 grow font-medium",
|
||||
{task.task().title()}
|
||||
},
|
||||
div {
|
||||
class: "flex flex-row gap-4",
|
||||
if let Some(deadline) = task.task().deadline() {
|
||||
div {
|
||||
class: "text-sm text-zinc-400",
|
||||
i {
|
||||
class: "fa-solid fa-bomb"
|
||||
},
|
||||
{deadline.format(" %m. %-d.").to_string()}
|
||||
}
|
||||
}
|
||||
if let Category::Calendar { time, .. } = task.task().category() {
|
||||
if let Some(calendar_time) = time {
|
||||
div {
|
||||
class: "text-sm text-zinc-400",
|
||||
i {
|
||||
class: "fa-solid fa-clock"
|
||||
},
|
||||
{calendar_time.time().format(" %k:%M").to_string()}
|
||||
}
|
||||
}
|
||||
}
|
||||
if !task.subtasks().is_empty() {
|
||||
div {
|
||||
class: "text-sm text-zinc-400",
|
||||
i {
|
||||
class: "fa-solid fa-list-check"
|
||||
},
|
||||
{format!(
|
||||
" {}/{}",
|
||||
task.subtasks().iter()
|
||||
.filter(|subtask| subtask.is_completed())
|
||||
.count(),
|
||||
task.subtasks().len()
|
||||
)}
|
||||
}
|
||||
}
|
||||
}
|
||||
TaskListItem {
|
||||
task: task.clone()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
61
src/components/task_list_item.rs
Normal file
61
src/components/task_list_item.rs
Normal file
@ -0,0 +1,61 @@
|
||||
use chrono::{Datelike, Local};
|
||||
use crate::models::category::Category;
|
||||
use crate::models::task::TaskWithSubtasks;
|
||||
use dioxus::core_macro::rsx;
|
||||
use dioxus::dioxus_core::Element;
|
||||
use dioxus::prelude::*;
|
||||
|
||||
#[component]
|
||||
pub(crate) fn TaskListItem(task: TaskWithSubtasks) -> Element {
|
||||
rsx! {
|
||||
div {
|
||||
class: "flex flex-col",
|
||||
div {
|
||||
class: "mt-1 grow font-medium",
|
||||
{task.task().title()}
|
||||
},
|
||||
div {
|
||||
class: "flex flex-row gap-4",
|
||||
if let Some(deadline) = task.task().deadline() {
|
||||
div {
|
||||
class: "text-sm text-zinc-400",
|
||||
i {
|
||||
class: "fa-solid fa-bomb"
|
||||
},
|
||||
{deadline.format(if deadline.year() == Local::now().year() {
|
||||
" %m. %-d."
|
||||
} else {
|
||||
" %m. %-d. %Y"
|
||||
}).to_string()}
|
||||
}
|
||||
}
|
||||
if let Category::Calendar { time, .. } = task.task().category() {
|
||||
if let Some(calendar_time) = time {
|
||||
div {
|
||||
class: "text-sm text-zinc-400",
|
||||
i {
|
||||
class: "fa-solid fa-clock"
|
||||
},
|
||||
{calendar_time.time().format(" %k:%M").to_string()}
|
||||
}
|
||||
}
|
||||
}
|
||||
if !task.subtasks().is_empty() {
|
||||
div {
|
||||
class: "text-sm text-zinc-400",
|
||||
i {
|
||||
class: "fa-solid fa-list-check"
|
||||
},
|
||||
{format!(
|
||||
" {}/{}",
|
||||
task.subtasks().iter()
|
||||
.filter(|subtask| subtask.is_completed())
|
||||
.count(),
|
||||
task.subtasks().len()
|
||||
)}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user
Approved:
TaskListItem
component implementation.The component is well-implemented with effective use of conditional rendering and UI elements. The handling of tasks, deadlines, and subtasks is appropriate and enhances user interaction.
Consider adding comments to complex conditional blocks for better maintainability and readability, especially for new developers or when revisiting the code later.