Fix use
issues
This commit is contained in:
parent
01ce1794cd
commit
0c62a41f70
@ -193,36 +193,3 @@ db_create_with_conn! {
|
||||
user_ids => Vec<jirs_data::UserId>,
|
||||
epic_id => Option<jirs_data::EpicId>
|
||||
}
|
||||
|
||||
// impl Handler<CreateIssue> for DbExecutor {
|
||||
// type Result = Result<Issue, crate::DatabaseError>;
|
||||
//
|
||||
// fn handle(&mut self, msg: CreateIssue, ctx: &mut Self::Context) -> Self::Result {
|
||||
// use crate::schema::issue_assignees::dsl;
|
||||
// use crate::schema::issues::dsl::issues;
|
||||
//
|
||||
// let mut values = vec![];
|
||||
// for user_id in msg.user_ids.iter() {
|
||||
// values.push(crate::models::CreateIssueAssigneeForm {
|
||||
// issue_id: issue.id,
|
||||
// user_id: *user_id,
|
||||
// });
|
||||
// }
|
||||
// if !msg.user_ids.contains(&msg.reporter_id) {
|
||||
// values.push(crate::models::CreateIssueAssigneeForm {
|
||||
// issue_id: issue.id,
|
||||
// user_id: msg.reporter_id,
|
||||
// });
|
||||
// }
|
||||
//
|
||||
// diesel::insert_into(dsl::issue_assignees)
|
||||
// .values(values)
|
||||
// .execute(conn)
|
||||
// .map_err(|e| {
|
||||
// log::error!("{:?}", e);
|
||||
// crate::DatabaseError::DatabaseConnectionLost
|
||||
// })?;
|
||||
//
|
||||
// Ok(issue)
|
||||
// }
|
||||
// }
|
||||
|
@ -64,52 +64,6 @@ db_create! {
|
||||
email => EmailString
|
||||
}
|
||||
|
||||
/*impl CreateUser {
|
||||
pub fn execute(self, conn: &DbPooledConn) -> Result<User, crate::DatabaseError> {
|
||||
use crate::schema::users::dsl::*;
|
||||
|
||||
q!(diesel::insert_into(users)
|
||||
.values((name.eq(self.name.as_str()), email.eq(self.email.as_str()))))
|
||||
.get_result(conn)
|
||||
.map_err(|e| {
|
||||
log::error!("{:?}", e);
|
||||
let ws = match e {
|
||||
Error::InvalidCString(_) => {
|
||||
crate::DatabaseError::User(UserError::InvalidPair(self.name, self.email))
|
||||
}
|
||||
Error::DatabaseError(diesel::result::DatabaseErrorKind::UniqueViolation, _) => {
|
||||
crate::DatabaseError::User(UserError::TakenPair(self.name, self.email))
|
||||
}
|
||||
Error::DatabaseError(_, _) => {
|
||||
crate::DatabaseError::User(UserError::InvalidPair(self.name, self.email))
|
||||
}
|
||||
Error::NotFound => {
|
||||
crate::DatabaseError::User(UserError::InvalidPair(self.name, self.email))
|
||||
}
|
||||
Error::QueryBuilderError(_) => {
|
||||
crate::DatabaseError::User(UserError::InvalidPair(self.name, self.email))
|
||||
}
|
||||
Error::DeserializationError(_) => {
|
||||
crate::DatabaseError::User(UserError::InvalidPair(self.name, self.email))
|
||||
}
|
||||
Error::SerializationError(_) => {
|
||||
crate::DatabaseError::User(UserError::InvalidPair(self.name, self.email))
|
||||
}
|
||||
Error::RollbackTransaction => {
|
||||
crate::DatabaseError::User(UserError::InvalidPair(self.name, self.email))
|
||||
}
|
||||
Error::AlreadyInTransaction => {
|
||||
crate::DatabaseError::User(UserError::InvalidPair(self.name, self.email))
|
||||
}
|
||||
Error::__Nonexhaustive => {
|
||||
crate::DatabaseError::User(UserError::InvalidPair(self.name, self.email))
|
||||
}
|
||||
};
|
||||
crate::DatabaseError::Error(ws)
|
||||
})
|
||||
}
|
||||
}*/
|
||||
|
||||
db_create_with_conn! {
|
||||
Register,
|
||||
msg => conn => users => {
|
||||
|
@ -1,6 +1,6 @@
|
||||
use jirs_data::HighlightedCode;
|
||||
use {
|
||||
actix::{Actor, Handler, SyncContext},
|
||||
jirs_data::HighlightedCode,
|
||||
std::sync::Arc,
|
||||
syntect::{
|
||||
easy::HighlightLines,
|
||||
|
@ -1,15 +1,9 @@
|
||||
#![allow(unused_imports)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
use std::io::BufRead;
|
||||
use std::{rc::Rc, sync::Arc};
|
||||
|
||||
use bincode::{deserialize_from, Result};
|
||||
use flate2::bufread::ZlibDecoder;
|
||||
use serde::de::DeserializeOwned;
|
||||
use syntect::easy::HighlightLines;
|
||||
use syntect::highlighting::ThemeSet;
|
||||
use syntect::parsing::SyntaxSet;
|
||||
use {
|
||||
bincode::{deserialize_from, Result},
|
||||
flate2::bufread::ZlibDecoder,
|
||||
serde::de::DeserializeOwned,
|
||||
std::io::BufRead,
|
||||
};
|
||||
|
||||
fn from_reader<T: DeserializeOwned, R: BufRead>(input: R) -> Result<T> {
|
||||
let mut decoder = ZlibDecoder::new(input);
|
||||
@ -29,17 +23,3 @@ pub fn integrated_syntaxset() -> syntect::parsing::SyntaxSet {
|
||||
pub fn integrated_themeset() -> syntect::highlighting::ThemeSet {
|
||||
from_binary(include_bytes!("./themes.bin"))
|
||||
}
|
||||
|
||||
pub fn load() -> (Rc<ThemeSet>, Rc<SyntaxSet>) {
|
||||
let theme_set = Rc::new(integrated_themeset());
|
||||
let syntax_set = Rc::new(integrated_syntaxset());
|
||||
(theme_set, syntax_set)
|
||||
}
|
||||
|
||||
pub fn arc() -> (Arc<ThemeSet>, Arc<SyntaxSet>) {
|
||||
use std::sync::Arc;
|
||||
|
||||
let theme_set = Arc::new(integrated_themeset());
|
||||
let syntax_set = Arc::new(integrated_syntaxset());
|
||||
(theme_set, syntax_set)
|
||||
}
|
||||
|
@ -1,9 +1,8 @@
|
||||
use actix::{Handler, Message};
|
||||
// use lettre;
|
||||
// use lettre_email;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::MailExecutor;
|
||||
use {
|
||||
crate::MailExecutor,
|
||||
actix::{Handler, Message},
|
||||
uuid::Uuid,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Invite {
|
||||
|
@ -1,7 +1,5 @@
|
||||
use actix::{Actor, SyncContext};
|
||||
|
||||
// use lettre;
|
||||
|
||||
pub mod invite;
|
||||
pub mod welcome;
|
||||
|
||||
@ -27,15 +25,18 @@ impl Default for MailExecutor {
|
||||
}
|
||||
|
||||
fn mail_client(config: &jirs_config::mail::Configuration) -> lettre::SmtpClient {
|
||||
let mail_user = config.user.as_str();
|
||||
let mail_pass = config.pass.as_str();
|
||||
let mail_host = config.host.as_str();
|
||||
let jirs_config::mail::Configuration {
|
||||
user: mail_user,
|
||||
pass: mail_pass,
|
||||
host: mail_host,
|
||||
..
|
||||
} = &config;
|
||||
|
||||
lettre::SmtpClient::new_simple(mail_host)
|
||||
.expect("Failed to init SMTP client")
|
||||
.credentials(lettre::smtp::authentication::Credentials::new(
|
||||
mail_user.to_string(),
|
||||
mail_pass.to_string(),
|
||||
mail_user.clone(),
|
||||
mail_pass.clone(),
|
||||
))
|
||||
.connection_reuse(lettre::smtp::ConnectionReuseParameters::ReuseUnlimited)
|
||||
.smtp_utf8(true)
|
||||
|
@ -1,9 +1,8 @@
|
||||
use actix::{Handler, Message};
|
||||
// use lettre;
|
||||
// use lettre_email;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::MailExecutor;
|
||||
use {
|
||||
crate::MailExecutor,
|
||||
actix::{Handler, Message},
|
||||
uuid::Uuid,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Welcome {
|
||||
|
@ -1,9 +1,9 @@
|
||||
use futures::executor::block_on;
|
||||
|
||||
use database_actor::issue_statuses;
|
||||
use jirs_data::{IssueStatusId, Position, TitleString, WsMsg};
|
||||
|
||||
use crate::{WebSocketActor, WsHandler, WsResult};
|
||||
use {
|
||||
crate::{WebSocketActor, WsHandler, WsResult},
|
||||
database_actor::issue_statuses,
|
||||
futures::executor::block_on,
|
||||
jirs_data::{IssueStatusId, Position, TitleString, WsMsg},
|
||||
};
|
||||
|
||||
pub struct LoadIssueStatuses;
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
use futures::executor::block_on;
|
||||
|
||||
use database_actor::messages;
|
||||
use jirs_data::{MessageId, WsMsg};
|
||||
|
||||
use crate::{WebSocketActor, WsHandler, WsResult};
|
||||
use {
|
||||
crate::{WebSocketActor, WsHandler, WsResult},
|
||||
database_actor::messages,
|
||||
futures::executor::block_on,
|
||||
jirs_data::{MessageId, WsMsg},
|
||||
};
|
||||
|
||||
pub struct LoadMessages;
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
use futures::executor::block_on;
|
||||
|
||||
use database_actor as db;
|
||||
use jirs_data::{UpdateProjectPayload, UserProject, WsMsg};
|
||||
|
||||
use crate::{WebSocketActor, WsHandler, WsResult};
|
||||
use {
|
||||
crate::{WebSocketActor, WsHandler, WsResult},
|
||||
database_actor as db,
|
||||
futures::executor::block_on,
|
||||
jirs_data::{UpdateProjectPayload, UserProject, WsMsg},
|
||||
};
|
||||
|
||||
impl WsHandler<UpdateProjectPayload> for WebSocketActor {
|
||||
fn handle_msg(&mut self, msg: UpdateProjectPayload, _ctx: &mut Self::Context) -> WsResult {
|
||||
|
@ -1,9 +1,9 @@
|
||||
use futures::executor::block_on;
|
||||
|
||||
use database_actor as db;
|
||||
use jirs_data::{UserProjectId, WsMsg};
|
||||
|
||||
use crate::{WebSocketActor, WsHandler, WsResult};
|
||||
use {
|
||||
crate::{WebSocketActor, WsHandler, WsResult},
|
||||
database_actor as db,
|
||||
futures::executor::block_on,
|
||||
jirs_data::{UserProjectId, WsMsg},
|
||||
};
|
||||
|
||||
pub struct LoadUserProjects;
|
||||
|
||||
|
@ -1,9 +1,8 @@
|
||||
use futures::executor::block_on;
|
||||
|
||||
use jirs_data::{UserId, UserProject, UserRole, WsMsg};
|
||||
use {
|
||||
crate::{handlers::auth::Authenticate, WebSocketActor, WsHandler, WsResult},
|
||||
database_actor::{self, users::Register as DbRegister},
|
||||
futures::executor::block_on,
|
||||
jirs_data::{UserId, UserProject, UserRole, WsMsg},
|
||||
};
|
||||
|
||||
pub struct LoadProjectUsers;
|
||||
|
@ -1,8 +1,8 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use actix::{Actor, Context, Recipient};
|
||||
|
||||
use jirs_data::{ProjectId, UserId, WsMsg};
|
||||
use {
|
||||
actix::{Actor, Context, Recipient},
|
||||
jirs_data::{ProjectId, UserId, WsMsg},
|
||||
std::collections::HashMap,
|
||||
};
|
||||
|
||||
#[derive(actix::Message, Debug)]
|
||||
#[rtype(result = "()")]
|
||||
|
@ -1,16 +1,21 @@
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::sync::{mpsc, Arc};
|
||||
use std::time::Duration;
|
||||
use std::{error::Error, io /*, thread*/};
|
||||
|
||||
// use termion::input::TermRead;
|
||||
use termion::{event::Key, input::MouseTerminal, raw::IntoRawMode, screen::AlternateScreen};
|
||||
use tui::{
|
||||
use {
|
||||
std::{
|
||||
error::Error,
|
||||
io,
|
||||
sync::{
|
||||
atomic::{AtomicBool, Ordering},
|
||||
mpsc, Arc,
|
||||
},
|
||||
time::Duration,
|
||||
},
|
||||
termion::{event::Key, input::MouseTerminal, raw::IntoRawMode, screen::AlternateScreen},
|
||||
tui::{
|
||||
backend::TermionBackend,
|
||||
layout::{Constraint, Direction, Layout},
|
||||
style::{Color, Style},
|
||||
widgets::{Block, Borders, Tabs},
|
||||
Terminal,
|
||||
},
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
|
@ -1,8 +1,5 @@
|
||||
use seed::{prelude::*, *};
|
||||
|
||||
use jirs_data::{TimeTracking, WsMsg};
|
||||
|
||||
use crate::{
|
||||
use {
|
||||
crate::{
|
||||
model::{self, ModalType, Model, Page},
|
||||
shared::{
|
||||
find_issue, go_to_board,
|
||||
@ -12,13 +9,12 @@ use crate::{
|
||||
},
|
||||
ws::send_ws_msg,
|
||||
FieldChange, FieldId, Msg, WebSocketChanged,
|
||||
},
|
||||
jirs_data::{TimeTracking, WsMsg},
|
||||
seed::{prelude::*, *},
|
||||
};
|
||||
|
||||
mod confirm_delete_issue;
|
||||
#[cfg(debug_assertions)]
|
||||
mod debug_modal;
|
||||
pub mod issues;
|
||||
pub mod time_tracking;
|
||||
|
||||
pub fn update(msg: &Msg, model: &mut model::Model, orders: &mut impl Orders<Msg>) {
|
||||
match msg {
|
||||
@ -102,7 +98,7 @@ pub fn view(model: &model::Model) -> Node<Msg> {
|
||||
empty![]
|
||||
}
|
||||
}
|
||||
ModalType::DeleteIssueConfirm(_id) => confirm_delete_issue::view(model),
|
||||
ModalType::DeleteIssueConfirm(_id) => crate::modals::issues_delete::view(model),
|
||||
ModalType::AddIssue(modal) => issues_create::view(model, modal),
|
||||
ModalType::DeleteCommentConfirm(comment_id) => {
|
||||
let comment_id = *comment_id;
|
||||
@ -114,12 +110,14 @@ pub fn view(model: &model::Model) -> Node<Msg> {
|
||||
.build()
|
||||
.into_node()
|
||||
}
|
||||
ModalType::TimeTracking(issue_id) => time_tracking::view(model, *issue_id),
|
||||
ModalType::TimeTracking(issue_id) => {
|
||||
crate::modals::time_tracking::view(model, *issue_id)
|
||||
}
|
||||
ModalType::DeleteIssueStatusModal(delete_issue_modal) => {
|
||||
issue_statuses_delete::view(model, delete_issue_modal.delete_id)
|
||||
}
|
||||
#[cfg(debug_assertions)]
|
||||
ModalType::DebugModal => debug_modal::view(model),
|
||||
ModalType::DebugModal => crate::modals::debug::view(model),
|
||||
})
|
||||
.collect();
|
||||
section![id!["modals"], modals]
|
||||
|
@ -1,17 +1,23 @@
|
||||
use seed::{prelude::*, *};
|
||||
use {
|
||||
crate::{
|
||||
model::{ModalType, Model},
|
||||
shared::{
|
||||
find_issue,
|
||||
styled_button::StyledButton,
|
||||
styled_field::StyledField,
|
||||
styled_input::{StyledInput, StyledInputState},
|
||||
styled_modal::StyledModal,
|
||||
styled_select::{StyledSelect, StyledSelectState},
|
||||
tracking_widget::{fibonacci_values, tracking_widget},
|
||||
ToChild, ToNode,
|
||||
},
|
||||
EditIssueModalSection, FieldId, Msg,
|
||||
},
|
||||
jirs_data::{IssueFieldId, IssueId, TimeTracking},
|
||||
seed::{prelude::*, *},
|
||||
};
|
||||
|
||||
use jirs_data::{IssueFieldId, IssueId, TimeTracking};
|
||||
|
||||
use crate::model::{ModalType, Model};
|
||||
use crate::shared::styled_button::StyledButton;
|
||||
use crate::shared::styled_field::StyledField;
|
||||
use crate::shared::styled_input::{StyledInput, StyledInputState};
|
||||
use crate::shared::styled_modal::StyledModal;
|
||||
use crate::shared::styled_select::{StyledSelect, StyledSelectState};
|
||||
use crate::shared::{find_issue, ToChild, ToNode};
|
||||
use crate::{EditIssueModalSection, FieldId, Msg};
|
||||
// use crate::shared::styled_select_child::*;
|
||||
use crate::shared::tracking_widget::{fibonacci_values, tracking_widget};
|
||||
|
||||
pub fn value_for_time_tracking(v: &Option<i32>, time_tracking_type: &TimeTracking) -> String {
|
||||
match (time_tracking_type, v.as_ref()) {
|
||||
@ -82,6 +88,7 @@ pub fn view(model: &Model, issue_id: IssueId) -> Node<Msg> {
|
||||
.into_node()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn time_tracking_field(
|
||||
time_tracking_type: TimeTracking,
|
||||
field_id: FieldId,
|
||||
|
5
jirs-client/src/modals/debug/mod.rs
Normal file
5
jirs-client/src/modals/debug/mod.rs
Normal file
@ -0,0 +1,5 @@
|
||||
pub use {model::*, update::*, view::*};
|
||||
|
||||
mod model;
|
||||
mod update;
|
||||
mod view;
|
0
jirs-client/src/modals/debug/model.rs
Normal file
0
jirs-client/src/modals/debug/model.rs
Normal file
0
jirs-client/src/modals/debug/update.rs
Normal file
0
jirs-client/src/modals/debug/update.rs
Normal file
@ -1,9 +1,11 @@
|
||||
use seed::{prelude::*, *};
|
||||
|
||||
use crate::model::Model;
|
||||
use crate::shared::styled_modal::StyledModal;
|
||||
use crate::shared::ToNode;
|
||||
use crate::Msg;
|
||||
use {
|
||||
crate::{
|
||||
model::Model,
|
||||
shared::{styled_modal::StyledModal, ToNode},
|
||||
Msg,
|
||||
},
|
||||
seed::{prelude::*, *},
|
||||
};
|
||||
|
||||
pub fn view(model: &Model) -> Node<Msg> {
|
||||
let text = format!("{:#?}", model);
|
@ -1,6 +1,4 @@
|
||||
pub use model::*;
|
||||
pub use update::*;
|
||||
pub use view::*;
|
||||
pub use {model::*, update::*, view::*};
|
||||
|
||||
mod model;
|
||||
mod update;
|
||||
|
@ -1,11 +1,11 @@
|
||||
use seed::prelude::*;
|
||||
|
||||
use jirs_data::IssueStatusId;
|
||||
|
||||
use crate::{
|
||||
use {
|
||||
crate::{
|
||||
model,
|
||||
shared::{styled_confirm_modal::StyledConfirmModal, ToNode},
|
||||
Msg,
|
||||
},
|
||||
jirs_data::IssueStatusId,
|
||||
seed::prelude::*,
|
||||
};
|
||||
|
||||
pub fn view(_model: &model::Model, issue_status_id: IssueStatusId) -> Node<Msg> {
|
||||
|
@ -1,6 +1,4 @@
|
||||
pub use model::*;
|
||||
pub use update::*;
|
||||
pub use view::*;
|
||||
pub use {model::*, update::*, view::*};
|
||||
|
||||
mod model;
|
||||
mod update;
|
||||
|
@ -10,10 +10,10 @@ use {
|
||||
};
|
||||
|
||||
pub fn update(msg: &Msg, model: &mut crate::model::Model, orders: &mut impl Orders<Msg>) {
|
||||
let modal = model.modals.iter_mut().find(|modal| match modal {
|
||||
ModalType::AddIssue(..) => true,
|
||||
_ => false,
|
||||
});
|
||||
let modal = model
|
||||
.modals
|
||||
.iter_mut()
|
||||
.find(|modal| matches!(modal, ModalType::AddIssue(..)));
|
||||
let modal = match modal {
|
||||
Some(ModalType::AddIssue(modal)) => modal,
|
||||
_ => return,
|
||||
|
@ -15,7 +15,7 @@ use {
|
||||
seed::{prelude::*, *},
|
||||
};
|
||||
|
||||
pub fn view(model: &Model, modal: &Box<AddIssueModal>) -> Node<Msg> {
|
||||
pub fn view(model: &Model, modal: &AddIssueModal) -> Node<Msg> {
|
||||
let issue_type = modal
|
||||
.type_state
|
||||
.values
|
||||
@ -64,11 +64,8 @@ pub fn view(model: &Model, modal: &Box<AddIssueModal>) -> Node<Msg> {
|
||||
let reporter_field = reporter_field(model, modal);
|
||||
let assignees_field = assignees_field(model, modal);
|
||||
let issue_priority_field = issue_priority_field(modal);
|
||||
let epic_field = epic_field(
|
||||
model,
|
||||
modal.as_ref(),
|
||||
FieldId::AddIssueModal(IssueFieldId::EpicName),
|
||||
);
|
||||
let epic_field =
|
||||
epic_field(model, modal, FieldId::AddIssueModal(IssueFieldId::EpicName));
|
||||
|
||||
form.add_field(short_summary_field)
|
||||
.add_field(description_field)
|
||||
@ -120,7 +117,7 @@ pub fn view(model: &Model, modal: &Box<AddIssueModal>) -> Node<Msg> {
|
||||
.into_node()
|
||||
}
|
||||
|
||||
fn issue_type_field(modal: &Box<AddIssueModal>) -> Node<Msg> {
|
||||
fn issue_type_field(modal: &AddIssueModal) -> Node<Msg> {
|
||||
let select_type = StyledSelect::build()
|
||||
.name("type")
|
||||
.normal()
|
||||
@ -148,7 +145,8 @@ fn issue_type_field(modal: &Box<AddIssueModal>) -> Node<Msg> {
|
||||
.into_node()
|
||||
}
|
||||
|
||||
fn short_summary_field(modal: &Box<AddIssueModal>) -> Node<Msg> {
|
||||
#[inline]
|
||||
fn short_summary_field(modal: &AddIssueModal) -> Node<Msg> {
|
||||
let short_summary = StyledInput::build()
|
||||
.state(&modal.title_state)
|
||||
.build(FieldId::AddIssueModal(IssueFieldId::Title))
|
||||
|
5
jirs-client/src/modals/issues_delete/mod.rs
Normal file
5
jirs-client/src/modals/issues_delete/mod.rs
Normal file
@ -0,0 +1,5 @@
|
||||
pub use {model::*, update::*, view::*};
|
||||
|
||||
mod model;
|
||||
mod update;
|
||||
mod view;
|
1
jirs-client/src/modals/issues_delete/model.rs
Normal file
1
jirs-client/src/modals/issues_delete/model.rs
Normal file
@ -0,0 +1 @@
|
||||
|
1
jirs-client/src/modals/issues_delete/update.rs
Normal file
1
jirs-client/src/modals/issues_delete/update.rs
Normal file
@ -0,0 +1 @@
|
||||
|
@ -1,9 +1,10 @@
|
||||
use seed::{prelude::*, *};
|
||||
|
||||
use crate::model::ModalType;
|
||||
use crate::shared::styled_confirm_modal::StyledConfirmModal;
|
||||
use crate::shared::ToNode;
|
||||
use crate::{model, Msg};
|
||||
use {
|
||||
crate::{
|
||||
model, model::ModalType, shared::styled_confirm_modal::StyledConfirmModal, shared::ToNode,
|
||||
Msg,
|
||||
},
|
||||
seed::{prelude::*, *},
|
||||
};
|
||||
|
||||
pub fn view(model: &model::Model) -> Node<Msg> {
|
||||
let opt_id = model
|
@ -1,6 +1,4 @@
|
||||
pub use model::*;
|
||||
pub use update::*;
|
||||
pub use view::*;
|
||||
pub use {model::*, update::*, view::*};
|
||||
|
||||
mod model;
|
||||
mod update;
|
||||
|
@ -1,10 +1,11 @@
|
||||
use {
|
||||
crate::{
|
||||
modal::time_tracking::value_for_time_tracking,
|
||||
modals::time_tracking::value_for_time_tracking,
|
||||
model::{CommentForm, IssueModal},
|
||||
shared::{
|
||||
styled_date_time_input::StyledDateTimeInputState, styled_editor::Mode,
|
||||
styled_input::StyledInputState, styled_select::StyledSelectState,
|
||||
styled_editor::StyledEditorState, styled_input::StyledInputState,
|
||||
styled_select::StyledSelectState,
|
||||
},
|
||||
EditIssueModalSection, FieldId, Msg,
|
||||
},
|
||||
@ -12,8 +13,6 @@ use {
|
||||
seed::prelude::*,
|
||||
};
|
||||
|
||||
use crate::shared::styled_editor::StyledEditorState;
|
||||
|
||||
#[derive(Clone, Debug, PartialOrd, PartialEq)]
|
||||
pub struct Model {
|
||||
pub id: IssueId,
|
||||
|
@ -1,7 +1,7 @@
|
||||
use {
|
||||
crate::{
|
||||
modal::{issues::epic_field, time_tracking::time_tracking_field},
|
||||
modals::issues_edit::Model as EditIssueModal,
|
||||
modal::issues::epic_field,
|
||||
modals::{issues_edit::Model as EditIssueModal, time_tracking::time_tracking_field},
|
||||
model::{ModalType, Model},
|
||||
shared::{
|
||||
styled_avatar::StyledAvatar, styled_button::StyledButton, styled_editor::StyledEditor,
|
||||
|
@ -1,3 +1,7 @@
|
||||
#[cfg(debug_assertions)]
|
||||
pub mod debug;
|
||||
pub mod issue_statuses_delete;
|
||||
pub mod issues_create;
|
||||
pub mod issues_delete;
|
||||
pub mod issues_edit;
|
||||
pub mod time_tracking;
|
||||
|
5
jirs-client/src/modals/time_tracking/mod.rs
Normal file
5
jirs-client/src/modals/time_tracking/mod.rs
Normal file
@ -0,0 +1,5 @@
|
||||
pub use {model::*, update::*, view::*};
|
||||
|
||||
mod model;
|
||||
mod update;
|
||||
mod view;
|
0
jirs-client/src/modals/time_tracking/model.rs
Normal file
0
jirs-client/src/modals/time_tracking/model.rs
Normal file
0
jirs-client/src/modals/time_tracking/update.rs
Normal file
0
jirs-client/src/modals/time_tracking/update.rs
Normal file
125
jirs-client/src/modals/time_tracking/view.rs
Normal file
125
jirs-client/src/modals/time_tracking/view.rs
Normal file
@ -0,0 +1,125 @@
|
||||
use {
|
||||
crate::{
|
||||
model::{ModalType, Model},
|
||||
shared::{
|
||||
find_issue,
|
||||
styled_button::StyledButton,
|
||||
styled_field::StyledField,
|
||||
styled_input::{StyledInput, StyledInputState},
|
||||
styled_modal::StyledModal,
|
||||
styled_select::{StyledSelect, StyledSelectState},
|
||||
tracking_widget::{fibonacci_values, tracking_widget},
|
||||
ToChild, ToNode,
|
||||
},
|
||||
EditIssueModalSection, FieldId, Msg,
|
||||
},
|
||||
jirs_data::{IssueFieldId, IssueId, TimeTracking},
|
||||
seed::{prelude::*, *},
|
||||
};
|
||||
|
||||
// use crate::shared::styled_select_child::*;
|
||||
|
||||
pub fn value_for_time_tracking(v: &Option<i32>, time_tracking_type: &TimeTracking) -> String {
|
||||
match (time_tracking_type, v.as_ref()) {
|
||||
(TimeTracking::Untracked, _) => "".to_string(),
|
||||
(TimeTracking::Fibonacci, Some(n)) => n.to_string(),
|
||||
(TimeTracking::Hourly, Some(n)) => format!("{:.1}", *n as f64 / 10.0f64),
|
||||
_ => "".to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn view(model: &Model, issue_id: IssueId) -> Node<Msg> {
|
||||
let _issue = match find_issue(model, issue_id) {
|
||||
Some(issue) => issue,
|
||||
_ => return empty![],
|
||||
};
|
||||
|
||||
let edit_issue_modal = match model.modals.get(0) {
|
||||
Some(ModalType::EditIssue(_, modal)) => modal,
|
||||
_ => return empty![],
|
||||
};
|
||||
let time_tracking_type = model
|
||||
.project
|
||||
.as_ref()
|
||||
.map(|p| p.time_tracking)
|
||||
.unwrap_or_else(|| TimeTracking::Untracked);
|
||||
|
||||
let modal_title = div![C!["modalTitle"], "Time tracking"];
|
||||
|
||||
let tracking = tracking_widget(model, edit_issue_modal);
|
||||
|
||||
let time_spent_field = time_tracking_field(
|
||||
time_tracking_type,
|
||||
FieldId::EditIssueModal(EditIssueModalSection::Issue(IssueFieldId::TimeSpent)),
|
||||
"Time spent",
|
||||
&edit_issue_modal.time_spent,
|
||||
&edit_issue_modal.time_spent_select,
|
||||
);
|
||||
let time_remaining_field = time_tracking_field(
|
||||
time_tracking_type,
|
||||
FieldId::EditIssueModal(EditIssueModalSection::Issue(IssueFieldId::TimeRemaining)),
|
||||
"Time remaining",
|
||||
&edit_issue_modal.time_remaining,
|
||||
&edit_issue_modal.time_remaining_select,
|
||||
);
|
||||
|
||||
let inputs = div![
|
||||
C!["inputs"],
|
||||
div![C!["inputContainer"], time_spent_field],
|
||||
div![C!["inputContainer"], time_remaining_field]
|
||||
];
|
||||
|
||||
let close = StyledButton::build()
|
||||
.text("Done")
|
||||
.on_click(mouse_ev(Ev::Click, |_| Msg::ModalDropped))
|
||||
.build()
|
||||
.into_node();
|
||||
|
||||
StyledModal::build()
|
||||
.add_class("timeTrackingModal")
|
||||
.children(vec![
|
||||
modal_title,
|
||||
tracking,
|
||||
inputs,
|
||||
div![C!["actions"], close],
|
||||
])
|
||||
.width(400)
|
||||
.build()
|
||||
.into_node()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn time_tracking_field(
|
||||
time_tracking_type: TimeTracking,
|
||||
field_id: FieldId,
|
||||
label: &str,
|
||||
input_state: &StyledInputState,
|
||||
select_state: &StyledSelectState,
|
||||
) -> Node<Msg> {
|
||||
let fibonacci_values = fibonacci_values();
|
||||
let input = match time_tracking_type {
|
||||
TimeTracking::Untracked => empty![],
|
||||
TimeTracking::Fibonacci => StyledSelect::build()
|
||||
.selected(
|
||||
select_state
|
||||
.values
|
||||
.iter()
|
||||
.map(|n| (*n).to_child())
|
||||
.collect(),
|
||||
)
|
||||
.state(select_state)
|
||||
.options(fibonacci_values.iter().map(|v| v.to_child()).collect())
|
||||
.build(field_id)
|
||||
.into_node(),
|
||||
TimeTracking::Hourly => StyledInput::build()
|
||||
.state(input_state)
|
||||
.valid(true)
|
||||
.build(field_id)
|
||||
.into_node(),
|
||||
};
|
||||
StyledField::build()
|
||||
.input(input)
|
||||
.label(label)
|
||||
.build()
|
||||
.into_node()
|
||||
}
|
@ -1,6 +1,4 @@
|
||||
pub use model::*;
|
||||
pub use update::*;
|
||||
pub use view::*;
|
||||
pub use {model::*, update::*, view::*};
|
||||
|
||||
mod model;
|
||||
mod update;
|
||||
|
@ -1,16 +1,15 @@
|
||||
use std::str::FromStr;
|
||||
|
||||
use seed::prelude::*;
|
||||
|
||||
use jirs_data::{fields::*, WsMsg};
|
||||
|
||||
use crate::{
|
||||
use {
|
||||
crate::{
|
||||
authorize_or_redirect,
|
||||
model::{Model, Page, PageContent},
|
||||
pages::invite_page::InvitePage,
|
||||
shared::write_auth_token,
|
||||
ws::send_ws_msg,
|
||||
FieldId, InvitationPageChange, Msg, PageChanged, WebSocketChanged,
|
||||
},
|
||||
jirs_data::{fields::*, WsMsg},
|
||||
seed::prelude::*,
|
||||
std::str::FromStr,
|
||||
};
|
||||
|
||||
pub fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
|
||||
|
@ -1,5 +1,4 @@
|
||||
pub use update::*;
|
||||
pub use view::*;
|
||||
pub use {model::*, update::*, view::*};
|
||||
|
||||
pub mod model;
|
||||
pub mod update;
|
||||
|
@ -1,11 +1,12 @@
|
||||
use jirs_data::{ProjectId, User, UsersFieldId};
|
||||
|
||||
use crate::{
|
||||
use {
|
||||
crate::{
|
||||
shared::{
|
||||
styled_image_input::StyledImageInputState, styled_input::StyledInputState,
|
||||
styled_select::StyledSelectState,
|
||||
},
|
||||
FieldId,
|
||||
},
|
||||
jirs_data::{ProjectId, User, UsersFieldId},
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -1,5 +1,4 @@
|
||||
pub use update::*;
|
||||
pub use view::*;
|
||||
pub use {model::*, update::*, view::*};
|
||||
|
||||
pub mod model;
|
||||
pub mod update;
|
||||
|
@ -1,8 +1,4 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use jirs_data::*;
|
||||
|
||||
use crate::shared::drag::DragState;
|
||||
use {crate::shared::drag::DragState, jirs_data::*, std::collections::HashMap};
|
||||
|
||||
#[derive(Default, Debug)]
|
||||
pub struct StatusIssueIds {
|
||||
@ -17,9 +13,6 @@ pub struct EpicIssuePerStatus {
|
||||
pub per_status_issues: Vec<StatusIssueIds>,
|
||||
}
|
||||
|
||||
// pub type VisibleIssueMap =
|
||||
// HashMap<EpicName, HashMap<(IssueStatusId, IssueStatusName), Vec<IssueId>>>;
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct ProjectPage {
|
||||
pub text_filter: String,
|
||||
@ -33,9 +26,9 @@ pub struct ProjectPage {
|
||||
impl ProjectPage {
|
||||
pub fn rebuild_visible(
|
||||
&mut self,
|
||||
epics: &Vec<Epic>,
|
||||
statuses: &Vec<IssueStatus>,
|
||||
issues: &Vec<Issue>,
|
||||
epics: &[Epic],
|
||||
statuses: &[IssueStatus],
|
||||
issues: &[Issue],
|
||||
user: &Option<User>,
|
||||
) {
|
||||
let mut map = vec![];
|
||||
@ -66,7 +59,7 @@ impl ProjectPage {
|
||||
let mut per_epic_map = EpicIssuePerStatus::default();
|
||||
per_epic_map.epic_name = epic.map(|(_, name)| name).unwrap_or_default().to_string();
|
||||
|
||||
for (current_status_id, issue_status_name) in statuses.clone() {
|
||||
for (current_status_id, issue_status_name) in statuses.to_owned() {
|
||||
let mut per_status_map = StatusIssueIds::default();
|
||||
per_status_map.status_id = current_status_id;
|
||||
per_status_map.status_name = issue_status_name.to_string();
|
||||
@ -111,8 +104,3 @@ fn issue_filter_with_only_my(issue: &Issue, only_my: bool, user: &Option<User>)
|
||||
let my_id = user.as_ref().map(|u| u.id).unwrap_or_default();
|
||||
!only_my || issue.user_ids.contains(&my_id)
|
||||
}
|
||||
|
||||
// #[inline]
|
||||
// fn issue_filter_with_only_recent(issue: &Issue, ids: &[IssueId]) -> bool {
|
||||
// ids.is_empty() || ids.contains(&issue.id)
|
||||
// }
|
||||
|
@ -4,14 +4,13 @@ use {
|
||||
pages::project_page::model::ProjectPage,
|
||||
shared::styled_select::StyledSelectChanged,
|
||||
ws::{board_load, send_ws_msg},
|
||||
BoardPageChange, EditIssueModalSection, FieldId, Msg, PageChanged, WebSocketChanged,
|
||||
BoardPageChange, EditIssueModalSection, FieldId, Msg, OperationKind, PageChanged,
|
||||
ResourceKind,
|
||||
},
|
||||
jirs_data::*,
|
||||
seed::prelude::Orders,
|
||||
};
|
||||
|
||||
use crate::{OperationKind, ResourceKind};
|
||||
|
||||
pub fn update(msg: Msg, model: &mut crate::model::Model, orders: &mut impl Orders<Msg>) {
|
||||
if model.user.is_none() {
|
||||
return;
|
||||
@ -32,8 +31,7 @@ pub fn update(msg: Msg, model: &mut crate::model::Model, orders: &mut impl Order
|
||||
};
|
||||
|
||||
match msg {
|
||||
Msg::WebSocketChange(WebSocketChanged::WsMsg(WsMsg::AuthorizeLoaded(..)))
|
||||
| Msg::UserChanged(..)
|
||||
Msg::UserChanged(..)
|
||||
| Msg::ProjectChanged(Some(..))
|
||||
| Msg::ChangePage(Page::Project)
|
||||
| Msg::ChangePage(Page::AddIssue)
|
||||
|
@ -236,21 +236,6 @@ fn project_issue(model: &Model, issue: &Issue) -> Node<Msg> {
|
||||
.into_node()
|
||||
})
|
||||
.collect();
|
||||
// let avatars: Vec<Node<Msg>> = model
|
||||
// .users
|
||||
// .iter()
|
||||
// .enumerate()
|
||||
// .filter(|(_, user)| issue.user_ids.contains(&user.id))
|
||||
// .map(|(idx, user)| {
|
||||
// StyledAvatar::build()
|
||||
// .size(24)
|
||||
// .name(user.name.as_str())
|
||||
// .avatar_url(user.avatar_url.as_deref().unwrap_or_default())
|
||||
// .user_index(idx)
|
||||
// .build()
|
||||
// .into_node()
|
||||
// })
|
||||
// .collect();
|
||||
|
||||
let issue_type_icon = StyledIcon::build(issue.issue_type.clone().into())
|
||||
.with_color(issue.issue_type.to_str())
|
||||
|
@ -1,6 +1,4 @@
|
||||
pub use model::*;
|
||||
pub use update::*;
|
||||
pub use view::*;
|
||||
pub use {model::*, update::*, view::*};
|
||||
|
||||
mod model;
|
||||
mod update;
|
||||
|
@ -1,11 +1,12 @@
|
||||
use jirs_data::{IssueStatusId, Project, ProjectFieldId, UpdateProjectPayload};
|
||||
|
||||
use crate::{
|
||||
use {
|
||||
crate::{
|
||||
shared::{
|
||||
drag::DragState, styled_checkbox::StyledCheckboxState, styled_input::StyledInputState,
|
||||
styled_select::StyledSelectState,
|
||||
},
|
||||
FieldId,
|
||||
},
|
||||
jirs_data::{IssueStatusId, Project, ProjectFieldId, UpdateProjectPayload},
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -18,7 +19,6 @@ pub struct ProjectSettingsPage {
|
||||
pub edit_column_id: Option<IssueStatusId>,
|
||||
pub creating_issue_status: bool,
|
||||
pub name: StyledInputState,
|
||||
// pub description_rte: StyledRteState,
|
||||
}
|
||||
|
||||
impl ProjectSettingsPage {
|
||||
@ -58,9 +58,6 @@ impl ProjectSettingsPage {
|
||||
FieldId::ProjectSettings(ProjectFieldId::IssueStatusName),
|
||||
"",
|
||||
),
|
||||
// description_rte: StyledRteState::new(FieldId::ProjectSettings(
|
||||
// ProjectFieldId::Description,
|
||||
// )),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
use {
|
||||
crate::{
|
||||
model::{Model, Page, PageContent},
|
||||
pages::project_settings_page::ProjectSettingsPage,
|
||||
shared::styled_select::StyledSelectChanged,
|
||||
ws::{board_load, send_ws_msg},
|
||||
FieldChange::TabChanged,
|
||||
@ -11,8 +12,6 @@ use {
|
||||
std::collections::HashSet,
|
||||
};
|
||||
|
||||
use crate::pages::project_settings_page::ProjectSettingsPage;
|
||||
|
||||
pub fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
|
||||
if model.page != Page::ProjectSettings {
|
||||
return;
|
||||
|
@ -1,10 +1,5 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use seed::{prelude::*, *};
|
||||
|
||||
use jirs_data::{IssueStatus, ProjectCategory, TimeTracking, ToVec};
|
||||
|
||||
use crate::{
|
||||
use {
|
||||
crate::{
|
||||
modals::issue_statuses_delete::Model as DeleteIssueStatusModal,
|
||||
model::{self, ModalType, Model, PageContent},
|
||||
pages::project_settings_page::ProjectSettingsPage,
|
||||
@ -22,6 +17,10 @@ use crate::{
|
||||
ToChild, ToNode,
|
||||
},
|
||||
FieldId, Msg, PageChanged, ProjectFieldId, ProjectPageChange,
|
||||
},
|
||||
jirs_data::{IssueStatus, ProjectCategory, TimeTracking, ToVec},
|
||||
seed::{prelude::*, *},
|
||||
std::collections::HashMap,
|
||||
};
|
||||
|
||||
// use crate::shared::styled_rte::StyledRte;
|
||||
@ -225,6 +224,7 @@ fn columns_section(model: &Model, page: &ProjectSettingsPage) -> Node<Msg> {
|
||||
.into_node()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn add_column(page: &ProjectSettingsPage, column_style: &str) -> Node<Msg> {
|
||||
let on_click = mouse_ev(Ev::Click, move |_| {
|
||||
Msg::PageChanged(PageChanged::ProjectSettings(
|
||||
@ -268,6 +268,7 @@ fn add_column(page: &ProjectSettingsPage, column_style: &str) -> Node<Msg> {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn column_preview(
|
||||
is: &IssueStatus,
|
||||
page: &ProjectSettingsPage,
|
||||
|
@ -1,5 +1,4 @@
|
||||
pub use update::*;
|
||||
pub use view::*;
|
||||
pub use {model::*, update::*, view::*};
|
||||
|
||||
pub mod model;
|
||||
pub mod update;
|
||||
|
@ -1,13 +1,13 @@
|
||||
use seed::prelude::*;
|
||||
|
||||
use jirs_data::WsMsg;
|
||||
|
||||
use crate::pages::reports_page::model::ReportsPage;
|
||||
use crate::{
|
||||
use {
|
||||
crate::{
|
||||
changes::{PageChanged, ReportsPageChange},
|
||||
model::{Model, Page, PageContent},
|
||||
pages::reports_page::model::ReportsPage,
|
||||
ws::board_load,
|
||||
Msg, WebSocketChanged,
|
||||
},
|
||||
jirs_data::WsMsg,
|
||||
seed::prelude::*,
|
||||
};
|
||||
|
||||
pub fn update(msg: Msg, model: &mut crate::model::Model, orders: &mut impl Orders<Msg>) {
|
||||
|
@ -1,15 +1,14 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use chrono::Datelike;
|
||||
use seed::{prelude::*, *};
|
||||
|
||||
use jirs_data::Issue;
|
||||
|
||||
use crate::pages::reports_page::model::ReportsPage;
|
||||
use crate::{
|
||||
use {
|
||||
crate::{
|
||||
model::{Model, PageContent},
|
||||
pages::reports_page::model::ReportsPage,
|
||||
shared::{inner_layout, styled_icon::StyledIcon, ToNode},
|
||||
Msg, PageChanged, ReportsPageChange,
|
||||
},
|
||||
chrono::Datelike,
|
||||
jirs_data::Issue,
|
||||
seed::{prelude::*, *},
|
||||
std::collections::HashMap,
|
||||
};
|
||||
|
||||
const SVG_MARGIN_X: u32 = 10;
|
||||
|
@ -1,5 +1,4 @@
|
||||
pub use update::*;
|
||||
pub use view::*;
|
||||
pub use {model::*, update::*, view::*};
|
||||
|
||||
pub mod model;
|
||||
pub mod update;
|
||||
|
@ -1,16 +1,15 @@
|
||||
use std::str::FromStr;
|
||||
|
||||
use seed::{prelude::*, *};
|
||||
use uuid::Uuid;
|
||||
|
||||
use jirs_data::{SignInFieldId, WsMsg};
|
||||
|
||||
use crate::pages::sign_in_page::model::SignInPage;
|
||||
use crate::{
|
||||
use {
|
||||
crate::{
|
||||
model::{self, Model, Page, PageContent},
|
||||
pages::sign_in_page::model::SignInPage,
|
||||
shared::write_auth_token,
|
||||
ws::send_ws_msg,
|
||||
FieldId, Msg, WebSocketChanged,
|
||||
},
|
||||
jirs_data::{SignInFieldId, WsMsg},
|
||||
seed::{prelude::*, *},
|
||||
std::str::FromStr,
|
||||
uuid::Uuid,
|
||||
};
|
||||
|
||||
pub fn update(msg: Msg, model: &mut model::Model, orders: &mut impl Orders<Msg>) {
|
||||
|
@ -1,6 +1,5 @@
|
||||
use seed::{prelude::*, *};
|
||||
|
||||
use crate::{
|
||||
use {
|
||||
crate::{
|
||||
model::{self, PageContent},
|
||||
shared::{
|
||||
outer_layout,
|
||||
@ -14,6 +13,8 @@ use crate::{
|
||||
},
|
||||
validations::{is_email, is_token},
|
||||
FieldId, Msg, SignInFieldId,
|
||||
},
|
||||
seed::{prelude::*, *},
|
||||
};
|
||||
|
||||
pub fn view(model: &model::Model) -> Node<Msg> {
|
||||
|
@ -1,5 +1,4 @@
|
||||
pub use update::*;
|
||||
pub use view::*;
|
||||
pub use {model::*, update::*, view::*};
|
||||
|
||||
pub mod model;
|
||||
pub mod update;
|
||||
|
@ -1,12 +1,12 @@
|
||||
use seed::prelude::*;
|
||||
|
||||
use jirs_data::{SignUpFieldId, WsMsg};
|
||||
|
||||
use crate::pages::sign_up_page::model::SignUpPage;
|
||||
use crate::{
|
||||
use {
|
||||
crate::{
|
||||
model::{self, Model, Page, PageContent},
|
||||
pages::sign_up_page::model::SignUpPage,
|
||||
ws::send_ws_msg,
|
||||
FieldId, Msg, WebSocketChanged,
|
||||
},
|
||||
jirs_data::{SignUpFieldId, WsMsg},
|
||||
seed::prelude::*,
|
||||
};
|
||||
|
||||
pub fn update(msg: Msg, model: &mut model::Model, orders: &mut impl Orders<Msg>) {
|
||||
|
@ -1,8 +1,5 @@
|
||||
use seed::{prelude::*, *};
|
||||
|
||||
use jirs_data::SignUpFieldId;
|
||||
|
||||
use crate::{
|
||||
use {
|
||||
crate::{
|
||||
model::{self, PageContent},
|
||||
shared::{
|
||||
outer_layout,
|
||||
@ -16,6 +13,9 @@ use crate::{
|
||||
},
|
||||
validations::is_email,
|
||||
FieldId, Msg,
|
||||
},
|
||||
jirs_data::SignUpFieldId,
|
||||
seed::{prelude::*, *},
|
||||
};
|
||||
|
||||
pub fn view(model: &model::Model) -> Node<Msg> {
|
||||
|
@ -1,5 +1,4 @@
|
||||
pub use update::*;
|
||||
pub use view::*;
|
||||
pub use {model::*, update::*, view::*};
|
||||
|
||||
pub mod model;
|
||||
pub mod update;
|
||||
|
@ -1,8 +1,7 @@
|
||||
use jirs_data::{Invitation, User, UserRole, UsersFieldId};
|
||||
|
||||
use crate::model::InvitationFormState;
|
||||
use crate::shared::styled_select::StyledSelectState;
|
||||
use crate::FieldId;
|
||||
use {
|
||||
crate::{model::InvitationFormState, shared::styled_select::StyledSelectState, FieldId},
|
||||
jirs_data::{Invitation, User, UserRole, UsersFieldId},
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct UsersPage {
|
||||
|
@ -1,13 +1,13 @@
|
||||
use seed::prelude::Orders;
|
||||
|
||||
use jirs_data::{InvitationState, UserRole, UsersFieldId, WsMsg};
|
||||
|
||||
use crate::pages::users_page::model::UsersPage;
|
||||
use crate::{
|
||||
use {
|
||||
crate::{
|
||||
model::{InvitationFormState, Model, Page, PageContent},
|
||||
pages::users_page::model::UsersPage,
|
||||
shared::styled_select::StyledSelectChanged,
|
||||
ws::{invitation_load, send_ws_msg},
|
||||
FieldId, Msg, PageChanged, UsersPageChange, WebSocketChanged,
|
||||
},
|
||||
jirs_data::{InvitationState, UserRole, UsersFieldId, WsMsg},
|
||||
seed::prelude::Orders,
|
||||
};
|
||||
|
||||
pub fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
|
||||
|
@ -1,16 +1,16 @@
|
||||
use seed::{prelude::*, *};
|
||||
|
||||
use jirs_data::{InvitationState, ToVec, UserRole, UsersFieldId};
|
||||
|
||||
use crate::{
|
||||
use {
|
||||
crate::{
|
||||
model::{InvitationFormState, Model, PageContent},
|
||||
shared::{
|
||||
inner_layout, styled_button::StyledButton, styled_field::StyledField,
|
||||
styled_form::StyledForm, styled_input::StyledInput, styled_select::StyledSelect, ToChild,
|
||||
ToNode,
|
||||
styled_form::StyledForm, styled_input::StyledInput, styled_select::StyledSelect,
|
||||
ToChild, ToNode,
|
||||
},
|
||||
validations::is_email,
|
||||
FieldId, Msg, PageChanged, UsersPageChange,
|
||||
},
|
||||
jirs_data::{InvitationState, ToVec, UserRole, UsersFieldId},
|
||||
seed::{prelude::*, *},
|
||||
};
|
||||
|
||||
pub fn view(model: &Model) -> Node<Msg> {
|
||||
|
@ -1,10 +1,10 @@
|
||||
use seed::{prelude::*, *};
|
||||
|
||||
use jirs_data::*;
|
||||
|
||||
use crate::{
|
||||
use {
|
||||
crate::{
|
||||
model::{Model, Page},
|
||||
resolve_page, Msg,
|
||||
},
|
||||
jirs_data::*,
|
||||
seed::{prelude::*, *},
|
||||
};
|
||||
|
||||
pub mod aside;
|
||||
@ -65,10 +65,12 @@ pub trait ToNode {
|
||||
fn into_node(self) -> Node<Msg>;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn divider() -> Node<Msg> {
|
||||
div![C!["divider"], ""]
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn inner_layout(model: &Model, page_name: &str, children: Vec<Node<Msg>>) -> Node<Msg> {
|
||||
let modal_node = crate::modal::view(model);
|
||||
article![
|
||||
@ -81,6 +83,7 @@ pub fn inner_layout(model: &Model, page_name: &str, children: Vec<Node<Msg>>) ->
|
||||
]
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn outer_layout(model: &Model, page_name: &str, children: Vec<Node<Msg>>) -> Node<Msg> {
|
||||
let modal = crate::modal::view(model);
|
||||
article![
|
||||
|
@ -1,8 +1,5 @@
|
||||
use seed::{prelude::*, *};
|
||||
|
||||
use jirs_data::{InvitationToken, Message, MessageType, WsMsg};
|
||||
|
||||
use crate::{
|
||||
use {
|
||||
crate::{
|
||||
model::Model,
|
||||
shared::{
|
||||
divider,
|
||||
@ -13,6 +10,9 @@ use crate::{
|
||||
},
|
||||
ws::send_ws_msg,
|
||||
Msg, Page,
|
||||
},
|
||||
jirs_data::{InvitationToken, Message, MessageType, WsMsg},
|
||||
seed::{prelude::*, *},
|
||||
};
|
||||
|
||||
trait IntoNavItemIcon {
|
||||
@ -45,7 +45,6 @@ pub fn render(model: &Model) -> Vec<Node<Msg>> {
|
||||
let logo_svg = img![
|
||||
attrs![At::Src => "/logo2.svg"; At::Style => "background: rgba(244,244,244,.8); border-radius: 24px;"]
|
||||
];
|
||||
// let logo_svg = Node::from_html(include_str!("../../static/logo.svg"));
|
||||
|
||||
let user_icon = match model.user.as_ref() {
|
||||
Some(user) => i![
|
||||
|
@ -38,6 +38,7 @@ pub struct StyledEditor {
|
||||
}
|
||||
|
||||
impl StyledEditor {
|
||||
#[inline]
|
||||
pub fn build(id: FieldId) -> StyledEditorBuilder {
|
||||
StyledEditorBuilder {
|
||||
id,
|
||||
@ -61,6 +62,7 @@ pub struct StyledEditorBuilder {
|
||||
}
|
||||
|
||||
impl StyledEditorBuilder {
|
||||
#[inline]
|
||||
pub fn text<S>(mut self, text: S) -> Self
|
||||
where
|
||||
S: Into<String>,
|
||||
@ -69,6 +71,7 @@ impl StyledEditorBuilder {
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn initial_text<S>(mut self, text: S) -> Self
|
||||
where
|
||||
S: Into<String>,
|
||||
@ -77,6 +80,7 @@ impl StyledEditorBuilder {
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn html<S>(mut self, text: S) -> Self
|
||||
where
|
||||
S: Into<String>,
|
||||
@ -85,11 +89,13 @@ impl StyledEditorBuilder {
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn mode(mut self, mode: Mode) -> Self {
|
||||
self.mode = mode;
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn build(self) -> StyledEditor {
|
||||
StyledEditor {
|
||||
id: self.id,
|
||||
@ -101,6 +107,7 @@ impl StyledEditorBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn update_on(mut self, ev: Ev) -> Self {
|
||||
self.update_event = Some(ev);
|
||||
self
|
||||
@ -108,11 +115,13 @@ impl StyledEditorBuilder {
|
||||
}
|
||||
|
||||
impl ToNode for StyledEditor {
|
||||
#[inline]
|
||||
fn into_node(self) -> Node<Msg> {
|
||||
render(self)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn render(values: StyledEditor) -> Node<Msg> {
|
||||
let StyledEditor {
|
||||
id,
|
||||
|
@ -1,7 +1,7 @@
|
||||
use seed::{prelude::*, *};
|
||||
|
||||
use crate::shared::ToNode;
|
||||
use crate::Msg;
|
||||
use {
|
||||
crate::{shared::ToNode, Msg},
|
||||
seed::{prelude::*, *},
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct StyledForm<'l> {
|
||||
@ -11,12 +11,14 @@ pub struct StyledForm<'l> {
|
||||
}
|
||||
|
||||
impl<'l> StyledForm<'l> {
|
||||
#[inline]
|
||||
pub fn build() -> StyledFormBuilder<'l> {
|
||||
StyledFormBuilder::default()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'l> ToNode for StyledForm<'l> {
|
||||
#[inline]
|
||||
fn into_node(self) -> Node<Msg> {
|
||||
render(self)
|
||||
}
|
||||
@ -30,11 +32,13 @@ pub struct StyledFormBuilder<'l> {
|
||||
}
|
||||
|
||||
impl<'l> StyledFormBuilder<'l> {
|
||||
#[inline]
|
||||
pub fn add_field(mut self, node: Node<Msg>) -> Self {
|
||||
self.fields.push(node);
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn try_field(mut self, node: Option<Node<Msg>>) -> Self {
|
||||
if let Some(n) = node {
|
||||
self.fields.push(n);
|
||||
@ -42,16 +46,19 @@ impl<'l> StyledFormBuilder<'l> {
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn heading(mut self, heading: &'l str) -> Self {
|
||||
self.heading = heading;
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn on_submit(mut self, on_submit: EventHandler<Msg>) -> Self {
|
||||
self.on_submit = Some(on_submit);
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn build(self) -> StyledForm<'l> {
|
||||
StyledForm {
|
||||
heading: self.heading,
|
||||
@ -61,6 +68,7 @@ impl<'l> StyledFormBuilder<'l> {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn render(values: StyledForm) -> Node<Msg> {
|
||||
let StyledForm {
|
||||
heading,
|
||||
@ -73,7 +81,7 @@ pub fn render(values: StyledForm) -> Node<Msg> {
|
||||
};
|
||||
seed::form![
|
||||
handlers,
|
||||
attrs![At::Class => "styledForm"],
|
||||
C!["styledForm"],
|
||||
div![C!["formElement"], div![C!["formHeading"], heading], fields],
|
||||
]
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ pub enum Variant {
|
||||
}
|
||||
|
||||
impl Variant {
|
||||
#[inline]
|
||||
pub fn to_str<'l>(&self) -> &'l str {
|
||||
match self {
|
||||
Variant::Normal => "normal",
|
||||
@ -20,6 +21,7 @@ impl Variant {
|
||||
}
|
||||
|
||||
impl ToString for Variant {
|
||||
#[inline]
|
||||
fn to_string(&self) -> String {
|
||||
self.to_str().to_string()
|
||||
}
|
||||
@ -33,6 +35,7 @@ pub struct StyledInputState {
|
||||
}
|
||||
|
||||
impl StyledInputState {
|
||||
#[inline]
|
||||
pub fn new<S>(id: FieldId, value: S) -> Self
|
||||
where
|
||||
S: Into<String>,
|
||||
@ -44,18 +47,22 @@ impl StyledInputState {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn to_i32(&self) -> Option<i32> {
|
||||
self.value.parse::<i32>().ok()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn to_f64(&self) -> Option<f64> {
|
||||
self.value.parse::<f64>().ok()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn represent_f64_as_i32(&self) -> Option<i32> {
|
||||
self.to_f64().map(|f| (f * 10.0f64) as i32)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn update(&mut self, msg: &Msg) {
|
||||
match msg {
|
||||
Msg::StrInputChanged(field_id, s) if field_id == &self.id => {
|
||||
@ -66,6 +73,7 @@ impl StyledInputState {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn reset(&mut self) {
|
||||
self.value.clear();
|
||||
}
|
||||
@ -86,6 +94,7 @@ pub struct StyledInput<'l> {
|
||||
}
|
||||
|
||||
impl<'l> StyledInput<'l> {
|
||||
#[inline]
|
||||
pub fn build() -> StyledInputBuilder<'l> {
|
||||
StyledInputBuilder {
|
||||
icon: None,
|
||||
@ -115,16 +124,19 @@ pub struct StyledInputBuilder<'l> {
|
||||
}
|
||||
|
||||
impl<'l> StyledInputBuilder<'l> {
|
||||
#[inline]
|
||||
pub fn icon(mut self, icon: Icon) -> Self {
|
||||
self.icon = Some(icon);
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn valid(mut self, valid: bool) -> Self {
|
||||
self.valid = Some(valid);
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn value<S>(mut self, v: S) -> Self
|
||||
where
|
||||
S: Into<String>,
|
||||
@ -133,36 +145,43 @@ impl<'l> StyledInputBuilder<'l> {
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn state(self, state: &StyledInputState) -> Self {
|
||||
self.value(state.value.as_str())
|
||||
.valid(!state.touched || !state.value.is_empty())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn add_input_class(mut self, name: &'l str) -> Self {
|
||||
self.input_class_list.push(name);
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn add_wrapper_class(mut self, name: &'l str) -> Self {
|
||||
self.wrapper_class_list.push(name);
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn primary(mut self) -> Self {
|
||||
self.variant = Variant::Primary;
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn auto_focus(mut self) -> Self {
|
||||
self.auto_focus = true;
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn on_input_ev(mut self, handler: EventHandler<Msg>) -> Self {
|
||||
self.input_handlers.push(handler);
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn build(self, id: FieldId) -> StyledInput<'l> {
|
||||
StyledInput {
|
||||
id,
|
||||
@ -180,6 +199,7 @@ impl<'l> StyledInputBuilder<'l> {
|
||||
}
|
||||
|
||||
impl<'l> ToNode for StyledInput<'l> {
|
||||
#[inline]
|
||||
fn into_node(self) -> Node<Msg> {
|
||||
render(self)
|
||||
}
|
||||
@ -209,10 +229,10 @@ pub fn render(values: StyledInput) -> Node<Msg> {
|
||||
input_class_list.push("withIcon");
|
||||
}
|
||||
|
||||
let icon = match icon {
|
||||
Some(icon) => StyledIcon::build(icon).build().into_node(),
|
||||
_ => empty![],
|
||||
};
|
||||
let icon = icon
|
||||
.map(|icon| StyledIcon::build(icon).build().into_node())
|
||||
.unwrap_or(Node::Empty);
|
||||
|
||||
let on_input = {
|
||||
let field_id = id.clone();
|
||||
ev(Ev::Input, move |event| {
|
||||
|
@ -1,7 +1,6 @@
|
||||
use {
|
||||
crate::{
|
||||
modal::time_tracking::value_for_time_tracking,
|
||||
modals::issues_edit::Model as EditIssueModal,
|
||||
modals::{issues_edit::Model as EditIssueModal, time_tracking::value_for_time_tracking},
|
||||
model::{ModalType, Model},
|
||||
shared::{
|
||||
styled_icon::{Icon, StyledIcon},
|
||||
|
@ -1,6 +1,7 @@
|
||||
use actix_web::HttpResponse;
|
||||
|
||||
use jirs_data::{msg::WsError, ErrorResponse};
|
||||
use {
|
||||
actix_web::HttpResponse,
|
||||
jirs_data::{msg::WsError, ErrorResponse},
|
||||
};
|
||||
|
||||
const TOKEN_NOT_FOUND: &str = "Token not found";
|
||||
const DATABASE_CONNECTION_FAILED: &str = "Database connection failed";
|
||||
|
@ -1,5 +1,7 @@
|
||||
use rusoto_signature::Region;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use {
|
||||
rusoto_signature::Region,
|
||||
serde::{Deserialize, Serialize},
|
||||
};
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct Configuration {
|
||||
|
@ -1,7 +1,7 @@
|
||||
use std::fs::{read_to_string, write};
|
||||
|
||||
use serde::export::PhantomData;
|
||||
use serde::{de::DeserializeOwned, Serialize};
|
||||
use {
|
||||
serde::{de::DeserializeOwned, export::PhantomData, Serialize},
|
||||
std::fs::{read_to_string, write},
|
||||
};
|
||||
|
||||
pub struct Reader<T: DeserializeOwned + Default + Serialize> {
|
||||
__phantom: PhantomData<T>,
|
||||
|
@ -1,17 +1,16 @@
|
||||
use std::cmp::Ordering;
|
||||
use std::str::FromStr;
|
||||
|
||||
use chrono::NaiveDateTime;
|
||||
#[cfg(feature = "backend")]
|
||||
use diesel::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
|
||||
pub use fields::*;
|
||||
pub use msg::WsMsg;
|
||||
pub use payloads::*;
|
||||
#[cfg(feature = "backend")]
|
||||
pub use sql::*;
|
||||
use {
|
||||
chrono::NaiveDateTime,
|
||||
serde::{Deserialize, Serialize},
|
||||
std::cmp::Ordering,
|
||||
std::str::FromStr,
|
||||
uuid::Uuid,
|
||||
};
|
||||
pub use {fields::*, msg::WsMsg, payloads::*};
|
||||
|
||||
pub mod fields;
|
||||
pub mod msg;
|
||||
|
@ -1,8 +1,9 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
CommentId, EpicId, Issue, IssueId, IssuePriority, IssueStatusId, IssueType, ProjectCategory,
|
||||
ProjectId, TimeTracking, UserId,
|
||||
use {
|
||||
crate::{
|
||||
CommentId, EpicId, Issue, IssueId, IssuePriority, IssueStatusId, IssueType,
|
||||
ProjectCategory, ProjectId, TimeTracking, UserId,
|
||||
},
|
||||
serde::{Deserialize, Serialize},
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
|
@ -1,9 +1,10 @@
|
||||
use std::io::Write;
|
||||
|
||||
use diesel::{deserialize::*, pg::*, serialize::*, *};
|
||||
|
||||
use crate::{
|
||||
InvitationState, IssuePriority, IssueType, MessageType, ProjectCategory, TimeTracking, UserRole,
|
||||
use {
|
||||
crate::{
|
||||
InvitationState, IssuePriority, IssueType, MessageType, ProjectCategory, TimeTracking,
|
||||
UserRole,
|
||||
},
|
||||
diesel::{deserialize::*, pg::*, serialize::*, *},
|
||||
std::io::Write,
|
||||
};
|
||||
|
||||
#[derive(SqlType)]
|
||||
|
Loading…
Reference in New Issue
Block a user