app,infra: Move more functionality in CommonComponent

This commit is contained in:
Valentin Tolmer 2021-10-31 21:19:54 +09:00 committed by nitnelave
parent ba72e622c2
commit 65dd1d1fd3
3 changed files with 58 additions and 30 deletions

View File

@ -176,7 +176,7 @@ impl CommonComponent<ChangePasswordForm> for ChangePasswordForm {
Ok(false)
}
Msg::RegistrationFinishResponse(response) => {
self.common.task = None;
self.common.cancel_task();
if response.is_ok() {
self.route_dispatcher
.send(RouteRequest::ChangeRoute(Route::from(
@ -236,7 +236,7 @@ impl Component for ChangePasswordForm {
class_invalid="is-invalid has-error"
class_valid="has-success"
autocomplete="current-password"
oninput=self.common.link.callback(|_| Msg::FormUpdate) />
oninput=self.common.callback(|_| Msg::FormUpdate) />
<div class="invalid-feedback">
{&self.form.field_message("old_password")}
</div>
@ -256,7 +256,7 @@ impl Component for ChangePasswordForm {
class_invalid="is-invalid has-error"
class_valid="has-success"
autocomplete="new-password"
oninput=self.common.link.callback(|_| Msg::FormUpdate) />
oninput=self.common.callback(|_| Msg::FormUpdate) />
<div class="invalid-feedback">
{&self.form.field_message("password")}
</div>
@ -275,7 +275,7 @@ impl Component for ChangePasswordForm {
class_invalid="is-invalid has-error"
class_valid="has-success"
autocomplete="new-password"
oninput=self.common.link.callback(|_| Msg::FormUpdate) />
oninput=self.common.callback(|_| Msg::FormUpdate) />
<div class="invalid-feedback">
{&self.form.field_message("confirm_password")}
</div>
@ -285,8 +285,8 @@ impl Component for ChangePasswordForm {
<button
class="btn btn-primary col-sm-1 col-form-label"
type="submit"
disabled=self.common.task.is_some()
onclick=self.common.link.callback(|e: MouseEvent| {e.prevent_default(); Msg::Submit})>
disabled=self.common.is_task_running()
onclick=self.common.callback(|e: MouseEvent| {e.prevent_default(); Msg::Submit})>
{"Submit"}
</button>
</div>

View File

@ -4,17 +4,11 @@ use crate::{
remove_user_from_group::RemoveUserFromGroupComponent,
router::{AppRoute, Link},
},
infra::{
common_component::{CommonComponent, CommonComponentParts},
api::HostService,
}
infra::common_component::{CommonComponent, CommonComponentParts},
};
use anyhow::{bail, Error, Result};
use graphql_client::GraphQLQuery;
use yew::{
prelude::*,
services::ConsoleService,
};
use yew::prelude::*;
#[derive(GraphQLQuery)]
#[graphql(
@ -53,18 +47,13 @@ pub struct Props {
impl GroupDetails {
fn get_group_details(&mut self) {
self.common.task = HostService::graphql_query::<GetGroupDetails>(
self.common.call_graphql::<GetGroupDetails, _>(
get_group_details::Variables {
id: self.common.group_id,
},
self.common.link.callback(Msg::GroupDetailsResponse),
Msg::GroupDetailsResponse,
"Error trying to fetch group details",
)
.map_err(|e| {
ConsoleService::log(&e.to_string());
e
})
.ok();
);
}
fn view_messages(&self, error: &Option<Error>) -> Html {
@ -95,8 +84,8 @@ impl GroupDetails {
<RemoveUserFromGroupComponent
username=user_id
group_id=g.id
on_user_removed_from_group=self.common.link.callback(Msg::OnUserRemovedFromGroup)
on_error=self.common.link.callback(Msg::OnError)/>
on_user_removed_from_group=self.common.callback(Msg::OnUserRemovedFromGroup)
on_error=self.common.callback(Msg::OnError)/>
</td>
</tr>
}
@ -145,8 +134,8 @@ impl GroupDetails {
<AddGroupMemberComponent
group_id=g.id
users=users
on_error=self.common.link.callback(Msg::OnError)
on_user_added_to_group=self.common.link.callback(Msg::OnUserAddedToGroup)/>
on_error=self.common.callback(Msg::OnError)
on_user_added_to_group=self.common.callback(Msg::OnUserAddedToGroup)/>
}
}
}

View File

@ -1,4 +1,6 @@
use crate::infra::api::HostService;
use anyhow::{Error, Result};
use graphql_client::GraphQLQuery;
use yew::{
prelude::*,
services::{fetch::FetchTask, ConsoleService},
@ -10,13 +12,21 @@ pub trait CommonComponent<C: Component + CommonComponent<C>>: Component {
}
pub struct CommonComponentParts<C: CommonComponent<C>> {
pub link: ComponentLink<C>,
link: ComponentLink<C>,
pub props: <C as Component>::Properties,
pub error: Option<Error>,
pub task: Option<FetchTask>,
task: Option<FetchTask>,
}
impl<C: CommonComponent<C>> CommonComponentParts<C> {
pub fn is_task_running(&self) -> bool {
self.task.is_some()
}
pub fn cancel_task(&mut self) {
self.task = None;
}
pub fn create(props: <C as Component>::Properties, link: ComponentLink<C>) -> Self {
Self {
link,
@ -38,6 +48,14 @@ impl<C: CommonComponent<C>> CommonComponentParts<C> {
}
}
pub fn callback<F, IN, M>(&self, function: F) -> Callback<IN>
where
M: Into<C::Message>,
F: Fn(IN) -> M + 'static,
{
self.link.callback(function)
}
pub fn call_backend<M, Req, Cb, Resp>(
&mut self,
method: M,
@ -46,11 +64,32 @@ impl<C: CommonComponent<C>> CommonComponentParts<C> {
) -> Result<()>
where
M: Fn(Req, Callback<Resp>) -> Result<FetchTask>,
Cb: Fn(Resp) -> <C as Component>::Message + 'static,
Cb: FnOnce(Resp) -> <C as Component>::Message + 'static,
{
self.task = Some(method(req, self.link.callback(callback))?);
self.task = Some(method(req, self.link.callback_once(callback))?);
Ok(())
}
pub fn call_graphql<QueryType, EnumCallback>(
&mut self,
variables: QueryType::Variables,
enum_callback: EnumCallback,
error_message: &'static str,
) where
QueryType: GraphQLQuery + 'static,
EnumCallback: Fn(Result<QueryType::ResponseData>) -> <C as Component>::Message + 'static,
{
self.task = HostService::graphql_query::<QueryType>(
variables,
self.link.callback(enum_callback),
error_message,
)
.map_err::<(), _>(|e| {
ConsoleService::log(&e.to_string());
self.error = Some(e);
})
.ok();
}
}
impl<C: Component + CommonComponent<C>> std::ops::Deref for CommonComponentParts<C> {