Handle reset invitation form. Sort invitation, skip accepted invitations.
This commit is contained in:
parent
5ccf93faab
commit
9fda6def09
@ -16,6 +16,10 @@
|
|||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#users > .invitationsSection > .invitationsList > .invitation.revoked {
|
||||||
|
color: var(--textLight);
|
||||||
|
}
|
||||||
|
|
||||||
#users > .invitationsSection > .invitationsList > .invitation > * {
|
#users > .invitationsSection > .invitationsList > .invitation > * {
|
||||||
width: 25%;
|
width: 25%;
|
||||||
}
|
}
|
||||||
|
@ -138,6 +138,16 @@ pub enum FieldChange {
|
|||||||
EditComment(FieldId, i32),
|
EditComment(FieldId, i32),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
pub enum UsersPageChange {
|
||||||
|
ResetForm,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
pub enum PageChanged {
|
||||||
|
Users(UsersPageChange),
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub enum Msg {
|
pub enum Msg {
|
||||||
NoOp,
|
NoOp,
|
||||||
@ -147,6 +157,7 @@ pub enum Msg {
|
|||||||
ctrl: bool,
|
ctrl: bool,
|
||||||
alt: bool,
|
alt: bool,
|
||||||
},
|
},
|
||||||
|
PageChanged(PageChanged),
|
||||||
|
|
||||||
// Auth Token
|
// Auth Token
|
||||||
AuthTokenStored,
|
AuthTokenStored,
|
||||||
|
@ -64,10 +64,10 @@ impl StyledButtonBuilder {
|
|||||||
self.variant(Variant::Empty)
|
self.variant(Variant::Empty)
|
||||||
}
|
}
|
||||||
|
|
||||||
// pub fn disabled(mut self, value: bool) -> Self {
|
pub fn disabled(mut self, value: bool) -> Self {
|
||||||
// self.disabled = Some(value);
|
self.disabled = Some(value);
|
||||||
// self
|
self
|
||||||
// }
|
}
|
||||||
|
|
||||||
pub fn active(mut self, value: bool) -> Self {
|
pub fn active(mut self, value: bool) -> Self {
|
||||||
self.active = Some(value);
|
self.active = Some(value);
|
||||||
|
@ -39,6 +39,15 @@ pub struct StyledSelectState {
|
|||||||
pub field_id: FieldId,
|
pub field_id: FieldId,
|
||||||
pub opened: bool,
|
pub opened: bool,
|
||||||
pub text_filter: String,
|
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 {
|
impl StyledSelectState {
|
||||||
@ -47,6 +56,7 @@ impl StyledSelectState {
|
|||||||
field_id,
|
field_id,
|
||||||
opened: false,
|
opened: false,
|
||||||
text_filter: String::new(),
|
text_filter: String::new(),
|
||||||
|
values: vec![],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,6 +75,23 @@ impl StyledSelectState {
|
|||||||
{
|
{
|
||||||
self.text_filter = text.clone();
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
use seed::{prelude::*, *};
|
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::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_button::StyledButton;
|
||||||
use crate::shared::styled_field::StyledField;
|
use crate::shared::styled_field::StyledField;
|
||||||
use crate::shared::styled_form::StyledForm;
|
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::styled_select_child::ToStyledSelectChild;
|
||||||
use crate::shared::{inner_layout, ToNode};
|
use crate::shared::{inner_layout, ToNode};
|
||||||
use crate::validations::is_email;
|
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>) {
|
pub fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
|
||||||
if let Msg::ChangePage(Page::Users) = 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)) => {
|
Msg::WsMsg(WsMsg::InvitationListLoaded(invitations)) => {
|
||||||
page.invitations = 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(
|
Msg::StyledSelectChanged(
|
||||||
FieldId::Users(UsersFieldId::UserRole),
|
FieldId::Users(UsersFieldId::UserRole),
|
||||||
StyledSelectChange::Changed(role),
|
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)) => {
|
Msg::WsMsg(WsMsg::InvitationRevokeSuccess(id)) => {
|
||||||
let mut old = vec![];
|
let mut old = vec![];
|
||||||
std::mem::swap(&mut page.invitations, &mut old);
|
std::mem::swap(&mut page.invitations, &mut old);
|
||||||
for invitation in old {
|
for mut invitation in old {
|
||||||
if invitation.id != id {
|
if id == invitation.id {
|
||||||
|
invitation.state = InvitationState::Revoked;
|
||||||
|
}
|
||||||
page.invitations.push(invitation);
|
page.invitations.push(invitation);
|
||||||
}
|
}
|
||||||
}
|
send_ws_msg(WsMsg::InvitationListRequest);
|
||||||
}
|
}
|
||||||
Msg::InviteRevokeRequest(invitation_id) => {
|
Msg::InviteRevokeRequest(invitation_id) => {
|
||||||
send_ws_msg(WsMsg::InvitationRevokeRequest(invitation_id));
|
send_ws_msg(WsMsg::InvitationRevokeRequest(invitation_id));
|
||||||
@ -161,6 +172,9 @@ pub fn view(model: &Model) -> Node<Msg> {
|
|||||||
.active(true)
|
.active(true)
|
||||||
.empty()
|
.empty()
|
||||||
.set_type_reset()
|
.set_type_reset()
|
||||||
|
.on_click(mouse_ev(Ev::Click, |_| {
|
||||||
|
Msg::PageChanged(PageChanged::Users(UsersPageChange::ResetForm))
|
||||||
|
}))
|
||||||
.text("Reset")
|
.text("Reset")
|
||||||
.build()
|
.build()
|
||||||
.into_node(),
|
.into_node(),
|
||||||
@ -218,11 +232,13 @@ pub fn view(model: &Model) -> Node<Msg> {
|
|||||||
let id = invitation.id;
|
let id = invitation.id;
|
||||||
let revoke = StyledButton::build()
|
let revoke = StyledButton::build()
|
||||||
.text("Revoke")
|
.text("Revoke")
|
||||||
|
.disabled(invitation.state == InvitationState::Revoked)
|
||||||
.on_click(mouse_ev(Ev::Click, move |_| Msg::InviteRevokeRequest(id)))
|
.on_click(mouse_ev(Ev::Click, move |_| Msg::InviteRevokeRequest(id)))
|
||||||
.build()
|
.build()
|
||||||
.into_node();
|
.into_node();
|
||||||
li![
|
li![
|
||||||
class!["invitation"],
|
class!["invitation"],
|
||||||
|
attrs![At::Class => format!("{}", invitation.state)],
|
||||||
span![invitation.name],
|
span![invitation.name],
|
||||||
span![invitation.email],
|
span![invitation.email],
|
||||||
span![format!("{}", invitation.state)],
|
span![format!("{}", invitation.state)],
|
||||||
|
@ -206,7 +206,7 @@ impl ToSql<UserRoleType, Pg> for UserRole {
|
|||||||
#[postgres(type_name = "InvitationStateType")]
|
#[postgres(type_name = "InvitationStateType")]
|
||||||
pub struct InvitationStateType;
|
pub struct InvitationStateType;
|
||||||
|
|
||||||
impl diesel::query_builder::QueryId for InvitationState {
|
impl diesel::query_builder::QueryId for InvitationStateType {
|
||||||
type QueryId = InvitationState;
|
type QueryId = InvitationState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +29,11 @@ impl Handler<ListInvitation> for DbExecutor {
|
|||||||
.get()
|
.get()
|
||||||
.map_err(|_| ServiceErrors::DatabaseConnectionLost)?;
|
.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());
|
debug!("{}", diesel::debug_query::<Pg, _>(&query).to_string());
|
||||||
query
|
query
|
||||||
.load(conn)
|
.load(conn)
|
||||||
@ -120,7 +124,10 @@ impl Handler<RevokeInvitation> for DbExecutor {
|
|||||||
.get()
|
.get()
|
||||||
.map_err(|_| ServiceErrors::DatabaseConnectionLost)?;
|
.map_err(|_| ServiceErrors::DatabaseConnectionLost)?;
|
||||||
let query = diesel::update(invitations)
|
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));
|
.filter(id.eq(msg.id));
|
||||||
debug!("{}", diesel::debug_query::<Pg, _>(&query).to_string());
|
debug!("{}", diesel::debug_query::<Pg, _>(&query).to_string());
|
||||||
query
|
query
|
||||||
@ -163,7 +170,10 @@ impl Handler<AcceptInvitation> for DbExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let query = diesel::update(invitations)
|
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(id.eq(invitation.id))
|
||||||
.filter(state.eq(InvitationState::Sent));
|
.filter(state.eq(InvitationState::Sent));
|
||||||
debug!("{}", diesel::debug_query::<Pg, _>(&query).to_string());
|
debug!("{}", diesel::debug_query::<Pg, _>(&query).to_string());
|
||||||
|
Loading…
Reference in New Issue
Block a user