feat: ability to edit a project #30

Merged
matous-volf merged 3 commits from feat/project-edit into main 2024-09-06 20:50:30 +00:00
7 changed files with 72 additions and 31 deletions
Showing only changes of commit b111fd4953 - Show all commits

View File

@ -2,6 +2,7 @@ use dioxus::prelude::*;
use crate::components::navigation::Navigation;
use crate::components::project_form::ProjectForm;
use crate::components::task_form::TaskForm;
use crate::models::project::Project;
use crate::route::Route;
#[component]
@ -12,8 +13,10 @@ pub(crate) fn BottomPanel(display_form: Signal<bool>) -> Element {
let navigation_expanded = use_signal(|| false);
let current_route = use_route();
use_effect(use_reactive(&display_form, move |creating_task| {
if creating_task() {
let mut project_being_edited = use_context::<Signal<Option<Project>>>();
use_effect(use_reactive(&display_form, move |display_form| {
if display_form() {
expanded.set(true);
} else {
spawn(async move {
@ -39,8 +42,10 @@ pub(crate) fn BottomPanel(display_form: Signal<bool>) -> Element {
match current_route {
Route::ProjectsPage => rsx! {
ProjectForm {
project: project_being_edited(),
on_successful_submit: move |_| {
display_form.set(false);
project_being_edited.set(None);
}
}
},

View File

@ -1,16 +0,0 @@
use dioxus::prelude::*;
#[component]
pub(crate) fn CreateButton(creating: Signal<bool>) -> Element {
rsx! {
button {
class: "m-4 py-3 px-5 self-end text-center bg-zinc-300/50 rounded-xl border-t-zinc-200 border-t backdrop-blur drop-shadow-[0_-5px_10px_rgba(0,0,0,0.2)] text-2xl text-zinc-200",
onclick: move |_| {
creating.set(!creating());
},
i {
class: format!("min-w-6 fa-solid {}", if creating() { "fa-xmark" } else { "fa-plus" }),
}
}
}
}

View File

@ -0,0 +1,22 @@
use dioxus::prelude::*;
use crate::models::project::Project;
#[component]
pub(crate) fn FormOpenButton(opened: Signal<bool>) -> Element {
let mut project_being_edited = use_context::<Signal<Option<Project>>>();
rsx! {
button {
class: "m-4 py-3 px-5 self-end text-center bg-zinc-300/50 rounded-xl border-t-zinc-200 border-t backdrop-blur drop-shadow-[0_-5px_10px_rgba(0,0,0,0.2)] text-2xl text-zinc-200",
onclick: move |_| {
if opened() {
project_being_edited.set(None);
}
opened.set(!opened());
},
i {
class: format!("min-w-6 fa-solid {}", if opened() { "fa-xmark" } else { "fa-plus" }),
}
}
}
}
coderabbitai[bot] commented 2024-09-06 18:34:38 +00:00 (Migrated from github.com)
Review

Approve the implementation but suggest adding documentation.

The implementation of the FormOpenButton component is approved as it effectively uses context and signals to manage and toggle the state of a project being edited. However, consider adding documentation to explain the component's functionality and its role within the project management system, especially how it interacts with other components and the state.

Would you like help with drafting the documentation for this component?

**Approve the implementation but suggest adding documentation.** The implementation of the `FormOpenButton` component is approved as it effectively uses context and signals to manage and toggle the state of a project being edited. However, consider adding documentation to explain the component's functionality and its role within the project management system, especially how it interacts with other components and the state. Would you like help with drafting the documentation for this component? <!-- This is an auto-generated comment by CodeRabbit -->

View File

@ -3,18 +3,26 @@ use crate::route::Route;
use dioxus::core_macro::rsx;
use dioxus::dioxus_core::Element;
use dioxus::prelude::*;
use crate::components::create_task_button::CreateButton;
use crate::components::form_open_button::FormOpenButton;
use crate::components::sticky_bottom::StickyBottom;
use crate::models::project::Project;
#[component]
pub(crate) fn Layout() -> Element {
let display_form = use_signal(|| false);
let mut display_form = use_signal(|| false);
let project_being_edited = use_context_provider::<Signal<Option<Project>>>(
|| Signal::new(None)
);
use_effect(move || {
display_form.set(project_being_edited().is_some());
});
rsx! {
Outlet::<Route> {}
StickyBottom {
CreateButton {
creating: display_form,
FormOpenButton {
opened: display_form,
}
BottomPanel {
display_form: display_form,

View File

@ -5,7 +5,7 @@ pub(crate) mod task_form;
pub(crate) mod task_list;
pub(crate) mod pages;
pub(crate) mod navigation;
pub(crate) mod create_task_button;
pub(crate) mod form_open_button;
pub(crate) mod bottom_panel;
pub(crate) mod sticky_bottom;
pub(crate) mod category_input;

View File

@ -1,11 +1,13 @@
use dioxus::prelude::*;
use dioxus_query::prelude::QueryResult;
use crate::models::project::Project;
use crate::query::projects::use_projects_query;
use crate::query::QueryValue;
#[component]
pub(crate) fn ProjectsPage() -> Element {
let projects_query = use_projects_query();
let mut project_being_edited = use_context::<Signal<Option<Project>>>();
rsx! {
match projects_query.result().value() {
@ -13,10 +15,18 @@ pub(crate) fn ProjectsPage() -> Element {
| QueryResult::Loading(Some(QueryValue::Projects(projects))) => rsx! {
div {
class: "flex flex-col",
for project in projects {
for project in projects.clone() {
div {
key: "{project.id()}",
class: "px-8 py-4",
class: format!(
"px-8 py-4 select-none {}",
if project_being_edited().map(|p| p.id()) == Some(project.id()) {
"bg-zinc-700"
} else { "" }
),
onclick: move |_| {
project_being_edited.set(Some(project.clone()));
},
{project.title()}
}
}

View File

@ -1,5 +1,5 @@
use crate::models::project::NewProject;
use crate::server::projects::create_project;
use crate::models::project::{NewProject, Project};
use crate::server::projects::{create_project, edit_project};
use dioxus::core_macro::{component, rsx};
use dioxus::dioxus_core::Element;
use dioxus::prelude::*;
@ -7,17 +7,28 @@ use dioxus_query::prelude::use_query_client;
use crate::query::{QueryErrors, QueryKey, QueryValue};
#[component]
pub(crate) fn ProjectForm(on_successful_submit: EventHandler<()>) -> Element {
pub(crate) fn ProjectForm(project: Option<Project>, on_successful_submit: EventHandler<()>)
-> Element {
let query_client = use_query_client::<QueryValue, QueryErrors, QueryKey>();
let project_for_submit = project.clone();
rsx! {
form {
onsubmit: move |event| {
let project_clone = project_for_submit.clone();
async move {
let new_project = NewProject::new(
event.values().get("title").unwrap().as_value()
);
let _ = create_project(new_project).await;
match project_clone {
Some(project) => {
let _ = edit_project(project.id(), new_project).await;
}
None => {
let _ = create_project(new_project).await;
}
}
query_client.invalidate_queries(&[
QueryKey::Projects
]);
@ -35,9 +46,10 @@ pub(crate) fn ProjectForm(on_successful_submit: EventHandler<()>) -> Element {
}
}
input {
r#type: "text",
name: "title",
required: true,
initial_value: project.map(|project| project.title().to_owned()),
r#type: "text",
class: "py-2 px-3 grow bg-zinc-800/50 rounded-lg",
id: "input_title"
}