use err ctx
This commit is contained in:
parent
5b49586da3
commit
d39596da77
@ -1,10 +1,13 @@
|
||||
use crate::components::error::error_provider::ErrorContext;
|
||||
use crate::services::rest::RestService;
|
||||
use common::Achievement;
|
||||
use common::ToggleAchievement;
|
||||
use std::rc::Rc;
|
||||
use wasm_bindgen_futures::spawn_local;
|
||||
use yew::classes;
|
||||
use yew::function_component;
|
||||
use yew::html;
|
||||
use yew::use_context;
|
||||
use yew::Callback;
|
||||
use yew::Html;
|
||||
use yew::Properties;
|
||||
@ -17,6 +20,8 @@ pub struct Props {
|
||||
|
||||
#[function_component]
|
||||
pub fn AchievementComponent(props: &Props) -> Html {
|
||||
let err_ctx = Rc::new(use_context::<ErrorContext>());
|
||||
|
||||
let Achievement {
|
||||
goal,
|
||||
completed,
|
||||
@ -28,10 +33,15 @@ pub fn AchievementComponent(props: &Props) -> Html {
|
||||
|
||||
let onclick_toggle = Callback::from(move |_| {
|
||||
log::info!("button click, toggling achievement");
|
||||
let err_ctx = Rc::clone(&err_ctx);
|
||||
spawn_local(async move {
|
||||
match RestService::toggle_achievement(ToggleAchievement { uuid }).await {
|
||||
Ok(_response) => {}
|
||||
Err(_err) => {}
|
||||
Err(err) => {
|
||||
if let Some(err_ctx) = &*err_ctx {
|
||||
err_ctx.dispatch(err.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -1,8 +1,10 @@
|
||||
use crate::components::error::error_provider::ErrorContext;
|
||||
use crate::services::confirm::ConfirmService;
|
||||
use crate::services::rest::RestService;
|
||||
use common::DeleteAchievement;
|
||||
use common::DeleteMilestone;
|
||||
use common::UpdateAchievementTimeOfReveal;
|
||||
use std::rc::Rc;
|
||||
use wasm_bindgen::JsCast;
|
||||
use wasm_bindgen_futures::spawn_local;
|
||||
use yew::function_component;
|
||||
@ -27,8 +29,9 @@ pub fn Admin() -> Html {
|
||||
.enumerate()
|
||||
.map(|(idx, a)| (idx + 1, a))
|
||||
.map(|(n, a)| {
|
||||
let uuid = a.uuid.to_string();
|
||||
html! {
|
||||
<Achievement number={n} achievement={a} />
|
||||
<Achievement key={uuid} number={n} achievement={a} />
|
||||
}
|
||||
})
|
||||
.collect::<Html>();
|
||||
@ -48,7 +51,10 @@ pub fn Admin() -> Html {
|
||||
milestones.sort_by_key(|m| m.goal);
|
||||
let milestones = milestones
|
||||
.into_iter()
|
||||
.map(|m| html! { <Milestone milestone={m}/> })
|
||||
.map(|m| {
|
||||
let uuid = m.uuid.to_string();
|
||||
html! { <Milestone key={uuid} milestone={m}/> }
|
||||
})
|
||||
.collect::<Html>();
|
||||
|
||||
html! {
|
||||
@ -93,6 +99,7 @@ struct AchievementProps {
|
||||
|
||||
#[function_component]
|
||||
fn Achievement(props: &AchievementProps) -> Html {
|
||||
let err_ctx = Rc::new(use_context::<ErrorContext>());
|
||||
let achievement = &props.achievement;
|
||||
let uuid = achievement.uuid;
|
||||
|
||||
@ -108,6 +115,7 @@ fn Achievement(props: &AchievementProps) -> Html {
|
||||
let awaiting_response = awaiting_response.clone();
|
||||
let timed_reveal_enabled = timed_reveal_enabled.clone();
|
||||
let input_time = input_time.clone();
|
||||
let err_ctx = Rc::clone(&err_ctx);
|
||||
Callback::from(move |e: web_sys::SubmitEvent| {
|
||||
e.prevent_default();
|
||||
|
||||
@ -129,8 +137,16 @@ fn Achievement(props: &AchievementProps) -> Html {
|
||||
};
|
||||
awaiting_response.set(true);
|
||||
let awaiting_response = awaiting_response.clone();
|
||||
let err_ctx = Rc::clone(&err_ctx);
|
||||
spawn_local(async move {
|
||||
let res = RestService::update_time_of_reveal(payload).await;
|
||||
match RestService::update_time_of_reveal(payload).await {
|
||||
Ok(_response) => {}
|
||||
Err(err) => {
|
||||
if let Some(err_ctx) = &*err_ctx {
|
||||
err_ctx.dispatch(err.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
awaiting_response.set(false);
|
||||
});
|
||||
})
|
||||
@ -163,10 +179,15 @@ fn Achievement(props: &AchievementProps) -> Html {
|
||||
}
|
||||
log::info!("Delete achievement confirmed.");
|
||||
|
||||
let err_ctx = Rc::clone(&err_ctx);
|
||||
spawn_local(async move {
|
||||
match RestService::delete_achievement(DeleteAchievement { uuid }).await {
|
||||
Ok(_response) => {}
|
||||
Err(_err) => {}
|
||||
Err(err) => {
|
||||
if let Some(err_ctx) = &*err_ctx {
|
||||
err_ctx.dispatch(err.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
@ -192,7 +213,7 @@ fn Achievement(props: &AchievementProps) -> Html {
|
||||
</div>
|
||||
|
||||
// Timed reveal form
|
||||
<form onsubmit={onsubmit_timed_reveal}>
|
||||
<form onsubmit={onsubmit_timed_reveal} style="margin-left: 30px">
|
||||
// Timed reveal: Enable checkbox
|
||||
<label>
|
||||
<span class="label-body" style="margin-right: 0.5rem; font-weight: bold"><i class="fas fa-clock" style="padding-right: 0.5em"/>{"Enable Timed Reveal:"}</span>
|
||||
@ -215,23 +236,27 @@ fn Achievement(props: &AchievementProps) -> Html {
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
<hr />
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
fn Milestone(props: &MilestoneProps) -> Html {
|
||||
let err_ctx = Rc::new(use_context::<ErrorContext>());
|
||||
let uuid = props.milestone.uuid;
|
||||
let onclick_delete = Callback::from(move |_| {
|
||||
if !ConfirmService::confirm("Are you sure you want to delete?") {
|
||||
return;
|
||||
}
|
||||
let err_ctx = Rc::clone(&err_ctx);
|
||||
spawn_local(async move {
|
||||
match RestService::delete_milestone(DeleteMilestone { uuid }).await {
|
||||
Ok(_response) => {}
|
||||
Err(_err) => {}
|
||||
Err(err) => {
|
||||
if let Some(err_ctx) = &*err_ctx {
|
||||
err_ctx.dispatch(err.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -1,4 +1,4 @@
|
||||
use super::error::error_provider::ErrorContext;
|
||||
use super::error::error_provider::get_error_context;
|
||||
use crate::services::rest::RestService;
|
||||
use crate::services::rest::RestServiceError;
|
||||
use common::CreateAchievement;
|
||||
@ -66,14 +66,12 @@ impl Component for CreateAchievementComponent {
|
||||
match result {
|
||||
Ok(_response) => {
|
||||
let nav = ctx.link().navigator().unwrap();
|
||||
nav.push(&crate::Route::Root);
|
||||
nav.push(&crate::Route::Admin);
|
||||
}
|
||||
Err(err) => {
|
||||
let (error_context, _context_listener) = ctx
|
||||
.link()
|
||||
.context(Callback::from(|_: ErrorContext| ()))
|
||||
.expect("No Error Context Provided");
|
||||
error_context.dispatch(err.to_string());
|
||||
if let Some(err_ctx) = get_error_context(ctx) {
|
||||
err_ctx.dispatch(err.to_string());
|
||||
}
|
||||
}
|
||||
};
|
||||
self.awaiting_response = false;
|
||||
|
@ -1,4 +1,4 @@
|
||||
use super::error::error_provider::ErrorContext;
|
||||
use super::error::error_provider::get_error_context;
|
||||
use crate::services::rest::RestService;
|
||||
use crate::services::rest::RestServiceError;
|
||||
use common::CreateMilestone;
|
||||
@ -67,14 +67,12 @@ impl Component for CreateMilestoneComponent {
|
||||
match result {
|
||||
Ok(_response) => {
|
||||
let nav = ctx.link().navigator().unwrap();
|
||||
nav.push(&crate::Route::Root);
|
||||
nav.push(&crate::Route::Admin)
|
||||
}
|
||||
Err(err) => {
|
||||
let (error_context, _context_listener) = ctx
|
||||
.link()
|
||||
.context(Callback::from(|_: ErrorContext| ()))
|
||||
.expect("No Error Context Provided");
|
||||
error_context.dispatch(err.to_string());
|
||||
if let Some(err_ctx) = get_error_context(ctx) {
|
||||
err_ctx.dispatch(err.to_string());
|
||||
}
|
||||
}
|
||||
};
|
||||
self.awaiting_response = false;
|
||||
@ -92,7 +90,7 @@ impl Component for CreateMilestoneComponent {
|
||||
let nav = ctx.link().navigator().unwrap();
|
||||
|
||||
let onclick_go_back = Callback::from(move |_: web_sys::MouseEvent| {
|
||||
nav.push(&crate::Route::Root);
|
||||
nav.push(&crate::Route::Admin);
|
||||
});
|
||||
|
||||
let onsubmit = link.callback(|e: web_sys::SubmitEvent| {
|
||||
|
@ -1,3 +1,5 @@
|
||||
//! This is the UI component that subscribes to and displays errors.
|
||||
|
||||
use super::error_provider::ErrorContext;
|
||||
use yew::prelude::*;
|
||||
|
||||
|
@ -41,3 +41,10 @@ pub fn ErrorProvider(props: &ErrorProviderProps) -> Html {
|
||||
</ContextProvider<ErrorContext>>
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper for struct components to get the error context
|
||||
pub fn get_error_context(ctx: &Context<impl yew::Component>) -> Option<ErrorContext> {
|
||||
ctx.link()
|
||||
.context(Callback::from(|_: ErrorContext| ()))
|
||||
.map(|(error_context, _context_handle)| error_context)
|
||||
}
|
||||
|
@ -3,11 +3,9 @@ use crate::components::milestone::MilestoneComponent;
|
||||
use crate::util::group_achievements::group_achievements;
|
||||
use yew::functional::*;
|
||||
use yew::prelude::*;
|
||||
use yew_router::prelude::*;
|
||||
|
||||
#[function_component]
|
||||
pub fn Root() -> Html {
|
||||
let nav = use_navigator().expect("cannot get navigator");
|
||||
let app_state = use_context::<crate::AppState>().expect("no app state ctx found");
|
||||
|
||||
let current_time: chrono::NaiveTime = chrono::Local::now().time();
|
||||
@ -21,7 +19,7 @@ pub fn Root() -> Html {
|
||||
if let Some(time_of_reveal) = time_of_reveal {
|
||||
let s = if time_of_reveal > current_time {
|
||||
format!(
|
||||
"{} more revealed at {}!",
|
||||
"Next {} revealed at {}!",
|
||||
group.len(),
|
||||
time_of_reveal.format("%H:%M")
|
||||
)
|
||||
@ -38,8 +36,9 @@ pub fn Root() -> Html {
|
||||
}
|
||||
for a in group {
|
||||
n += 1;
|
||||
let uuid = a.uuid.to_string();
|
||||
let html = html! {
|
||||
<AchievementComponent number={n} achievement={a} />
|
||||
<AchievementComponent key={uuid} number={n} achievement={a} />
|
||||
};
|
||||
achievements_html.push(html);
|
||||
}
|
||||
@ -55,7 +54,7 @@ pub fn Root() -> Html {
|
||||
|
||||
let mut milestones = app_state.state.milestones.clone();
|
||||
milestones.sort_by_key(|m| m.goal);
|
||||
let milestones = milestones.into_iter().map(|m| html! { <MilestoneComponent milestone={m} completed_achievements={completed_achievements} /> }).collect::<Html>();
|
||||
let milestones = milestones.into_iter().map(|m| {let uuid = m.uuid.to_string(); html! { <MilestoneComponent key={uuid} milestone={m} completed_achievements={completed_achievements} /> }}).collect::<Html>();
|
||||
|
||||
html! {
|
||||
<>
|
||||
|
@ -41,7 +41,7 @@ impl RestService {
|
||||
})?;
|
||||
|
||||
if let Ok(rest_response) = response.json::<RestResponse<T>>().await {
|
||||
return rest_response.map_err(Into::into);
|
||||
return rest_response.map_err(RestServiceError::RestError);
|
||||
}
|
||||
|
||||
let err = RestServiceError::UnexpectedResponse(response);
|
||||
|
@ -38,7 +38,7 @@ mod tests {
|
||||
let time1 = NaiveTime::from_hms_opt(12, 0, 0).unwrap();
|
||||
let time2 = NaiveTime::from_hms_opt(13, 0, 0).unwrap();
|
||||
|
||||
let mut achievements = vec![
|
||||
let achievements = vec![
|
||||
Achievement {
|
||||
goal: "Goal 1".to_string(),
|
||||
completed: true,
|
||||
|
Loading…
x
Reference in New Issue
Block a user