Handle reset invitation form. Sort invitation, skip accepted invitations.

This commit is contained in:
Adrian Wozniak 2020-04-24 16:20:50 +02:00
parent 5ccf93faab
commit 9fda6def09
7 changed files with 82 additions and 14 deletions

View File

@ -16,6 +16,10 @@
margin-top: 20px;
}
#users > .invitationsSection > .invitationsList > .invitation.revoked {
color: var(--textLight);
}
#users > .invitationsSection > .invitationsList > .invitation > * {
width: 25%;
}

View File

@ -138,6 +138,16 @@ pub enum FieldChange {
EditComment(FieldId, i32),
}
#[derive(Clone, Debug, PartialEq)]
pub enum UsersPageChange {
ResetForm,
}
#[derive(Clone, Debug, PartialEq)]
pub enum PageChanged {
Users(UsersPageChange),
}
#[derive(Clone, Debug, PartialEq)]
pub enum Msg {
NoOp,
@ -147,6 +157,7 @@ pub enum Msg {
ctrl: bool,
alt: bool,
},
PageChanged(PageChanged),
// Auth Token
AuthTokenStored,

View File

@ -64,10 +64,10 @@ impl StyledButtonBuilder {
self.variant(Variant::Empty)
}
// pub fn disabled(mut self, value: bool) -> Self {
// self.disabled = Some(value);
// self
// }
pub fn disabled(mut self, value: bool) -> Self {
self.disabled = Some(value);
self
}
pub fn active(mut self, value: bool) -> Self {
self.active = Some(value);

View File

@ -39,6 +39,15 @@ pub struct StyledSelectState {
pub field_id: FieldId,
pub opened: bool,
pub text_filter: String,
pub values: Vec<u32>,
}
impl StyledSelectState {
pub fn reset(&mut self) {
self.text_filter.clear();
self.opened = false;
self.values = vec![];
}
}
impl StyledSelectState {
@ -47,6 +56,7 @@ impl StyledSelectState {
field_id,
opened: false,
text_filter: String::new(),
values: vec![],
}
}
@ -65,6 +75,23 @@ impl StyledSelectState {
{
self.text_filter = text.clone();
}
Msg::StyledSelectChanged(field_id, StyledSelectChange::Changed(v))
if field_id == &self.field_id =>
{
self.values = vec![*v];
}
Msg::StyledSelectChanged(field_id, StyledSelectChange::RemoveMulti(v))
if field_id == &self.field_id =>
{
let mut old = vec![];
std::mem::swap(&mut old, &mut self.values);
for u in old {
if u != *v {
self.values.push(u);
}
}
}
_ => (),
}
}

View File

@ -1,9 +1,9 @@
use seed::{prelude::*, *};
use jirs_data::{ToVec, UserRole, UsersFieldId, WsMsg};
use jirs_data::{InvitationState, ToVec, UserRole, UsersFieldId, WsMsg};
use crate::api::send_ws_msg;
use crate::model::{InvitationFormState, Model, Page, PageContent, UsersPage};
use crate::model::*;
use crate::shared::styled_button::StyledButton;
use crate::shared::styled_field::StyledField;
use crate::shared::styled_form::StyledForm;
@ -12,7 +12,7 @@ use crate::shared::styled_select::*;
use crate::shared::styled_select_child::ToStyledSelectChild;
use crate::shared::{inner_layout, ToNode};
use crate::validations::is_email;
use crate::{FieldId, Msg};
use crate::{FieldId, Msg, PageChanged, UsersPageChange};
pub fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
if let Msg::ChangePage(Page::Users) = msg {
@ -40,6 +40,15 @@ pub fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
Msg::WsMsg(WsMsg::InvitationListLoaded(invitations)) => {
page.invitations = invitations;
}
Msg::PageChanged(PageChanged::Users(UsersPageChange::ResetForm)) => {
page.name.clear();
page.name_touched = false;
page.email.clear();
page.email_touched = false;
page.user_role = UserRole::User;
page.user_role_state.reset();
page.form_state = InvitationFormState::Initial;
}
Msg::StyledSelectChanged(
FieldId::Users(UsersFieldId::UserRole),
StyledSelectChange::Changed(role),
@ -64,11 +73,13 @@ pub fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
Msg::WsMsg(WsMsg::InvitationRevokeSuccess(id)) => {
let mut old = vec![];
std::mem::swap(&mut page.invitations, &mut old);
for invitation in old {
if invitation.id != id {
page.invitations.push(invitation);
for mut invitation in old {
if id == invitation.id {
invitation.state = InvitationState::Revoked;
}
page.invitations.push(invitation);
}
send_ws_msg(WsMsg::InvitationListRequest);
}
Msg::InviteRevokeRequest(invitation_id) => {
send_ws_msg(WsMsg::InvitationRevokeRequest(invitation_id));
@ -161,6 +172,9 @@ pub fn view(model: &Model) -> Node<Msg> {
.active(true)
.empty()
.set_type_reset()
.on_click(mouse_ev(Ev::Click, |_| {
Msg::PageChanged(PageChanged::Users(UsersPageChange::ResetForm))
}))
.text("Reset")
.build()
.into_node(),
@ -218,11 +232,13 @@ pub fn view(model: &Model) -> Node<Msg> {
let id = invitation.id;
let revoke = StyledButton::build()
.text("Revoke")
.disabled(invitation.state == InvitationState::Revoked)
.on_click(mouse_ev(Ev::Click, move |_| Msg::InviteRevokeRequest(id)))
.build()
.into_node();
li![
class!["invitation"],
attrs![At::Class => format!("{}", invitation.state)],
span![invitation.name],
span![invitation.email],
span![format!("{}", invitation.state)],

View File

@ -206,7 +206,7 @@ impl ToSql<UserRoleType, Pg> for UserRole {
#[postgres(type_name = "InvitationStateType")]
pub struct InvitationStateType;
impl diesel::query_builder::QueryId for InvitationState {
impl diesel::query_builder::QueryId for InvitationStateType {
type QueryId = InvitationState;
}

View File

@ -29,7 +29,11 @@ impl Handler<ListInvitation> for DbExecutor {
.get()
.map_err(|_| ServiceErrors::DatabaseConnectionLost)?;
let query = invitations.filter(invited_by_id.eq(msg.user_id));
let query = invitations
.filter(invited_by_id.eq(msg.user_id))
.filter(state.ne(InvitationState::Accepted))
.order_by(state.asc())
.then_order_by(updated_at.desc());
debug!("{}", diesel::debug_query::<Pg, _>(&query).to_string());
query
.load(conn)
@ -120,7 +124,10 @@ impl Handler<RevokeInvitation> for DbExecutor {
.get()
.map_err(|_| ServiceErrors::DatabaseConnectionLost)?;
let query = diesel::update(invitations)
.set(state.eq(InvitationState::Revoked))
.set((
state.eq(InvitationState::Revoked),
updated_at.eq(chrono::Utc::now().naive_utc()),
))
.filter(id.eq(msg.id));
debug!("{}", diesel::debug_query::<Pg, _>(&query).to_string());
query
@ -163,7 +170,10 @@ impl Handler<AcceptInvitation> for DbExecutor {
}
let query = diesel::update(invitations)
.set(state.eq(InvitationState::Accepted))
.set((
state.eq(InvitationState::Accepted),
updated_at.eq(chrono::Utc::now().naive_utc()),
))
.filter(id.eq(invitation.id))
.filter(state.eq(InvitationState::Sent));
debug!("{}", diesel::debug_query::<Pg, _>(&query).to_string());