Better fmt, remove select builder

This commit is contained in:
Adrian Woźniak 2021-04-16 15:20:25 +02:00
parent e6ef4d6b0e
commit 2b40f9fd91
144 changed files with 1731 additions and 1935 deletions

View File

@ -1,7 +1,5 @@
use {
actix,
rusoto_s3::{PutObjectRequest, S3Client, S3},
};
use actix;
use rusoto_s3::{PutObjectRequest, S3Client, S3};
#[derive(Debug)]
pub enum AmazonError {

View File

@ -1,8 +1,8 @@
use {
crate::{db_find, tokens::FindAccessToken},
diesel::prelude::*,
jirs_data::User,
};
use diesel::prelude::*;
use jirs_data::User;
use crate::db_find;
use crate::tokens::FindAccessToken;
db_find! {
AuthorizeUser,

View File

@ -1,8 +1,7 @@
use {
crate::{db_create, db_delete, db_load, db_update},
diesel::prelude::*,
jirs_data::{Comment, CommentId, IssueId, UserId},
};
use diesel::prelude::*;
use jirs_data::{Comment, CommentId, IssueId, UserId};
use crate::{db_create, db_delete, db_load, db_update};
db_load! {
LoadIssueComments,

View File

@ -1,9 +1,8 @@
use {
crate::{db_create, db_delete, db_load, db_update},
derive_db_execute::Execute,
diesel::prelude::*,
jirs_data::{DescriptionString, Epic, EpicId, ProjectId},
};
use derive_db_execute::Execute;
use diesel::prelude::*;
use jirs_data::{DescriptionString, Epic, EpicId, ProjectId};
use crate::{db_create, db_delete, db_load, db_update};
#[derive(Execute)]
#[db_exec(schema = "epics", result = "Epic", find = "epics.find(msg.epic_id)")]

View File

@ -1,16 +1,15 @@
use {
crate::{
db_create, db_delete, db_find, db_load, db_pool, db_update,
tokens::CreateBindToken,
users::{LookupUser, Register},
DbExecutor, DbPooledConn, InvitationError,
},
actix::{Handler, Message},
diesel::prelude::*,
jirs_data::{
use actix::{Handler, Message};
use diesel::prelude::*;
use jirs_data::{
EmailString, Invitation, InvitationId, InvitationState, InvitationToken, ProjectId, Token,
User, UserId, UserRole, UsernameString,
},
};
use crate::tokens::CreateBindToken;
use crate::users::{LookupUser, Register};
use crate::{
db_create, db_delete, db_find, db_load, db_pool, db_update, DbExecutor, DbPooledConn,
InvitationError,
};
db_find! {

View File

@ -1,8 +1,8 @@
use {
crate::{db_create, db_delete, db_load, db_load_field},
diesel::{expression::dsl::not, prelude::*},
jirs_data::{IssueAssignee, IssueId, UserId},
};
use diesel::expression::dsl::not;
use diesel::prelude::*;
use jirs_data::{IssueAssignee, IssueId, UserId};
use crate::{db_create, db_delete, db_load, db_load_field};
db_create! {
AsignMultiple,

View File

@ -1,8 +1,7 @@
use {
crate::{db_create, db_delete, db_load, db_update},
diesel::prelude::*,
jirs_data::{IssueStatus, IssueStatusId, Position, ProjectId, TitleString},
};
use diesel::prelude::*;
use jirs_data::{IssueStatus, IssueStatusId, Position, ProjectId, TitleString};
use crate::{db_create, db_delete, db_load, db_update};
db_load! {
LoadIssueStatuses,

View File

@ -1,9 +1,9 @@
use {
crate::models::Issue,
derive_db_execute::Execute,
diesel::{expression::sql_literal::sql, prelude::*},
jirs_data::{IssueId, IssuePriority, IssueStatusId, IssueType, ProjectId, UserId},
};
use derive_db_execute::Execute;
use diesel::expression::sql_literal::sql;
use diesel::prelude::*;
use jirs_data::{IssueId, IssuePriority, IssueStatusId, IssueType, ProjectId, UserId};
use crate::models::Issue;
#[derive(Default, Execute)]
#[db_exec(
@ -112,12 +112,11 @@ pub struct DeleteIssue {
}
mod inner {
use {
crate::models::Issue,
derive_db_execute::Execute,
diesel::prelude::*,
jirs_data::{IssuePriority, IssueStatusId, IssueType},
};
use derive_db_execute::Execute;
use diesel::prelude::*;
use jirs_data::{IssuePriority, IssueStatusId, IssueType};
use crate::models::Issue;
#[derive(Default, Execute)]
#[db_exec(

View File

@ -3,12 +3,10 @@
#[macro_use]
extern crate diesel;
use actix::{Actor, SyncContext};
use diesel::pg::PgConnection;
use diesel::r2d2::{self, ConnectionManager};
pub use errors::*;
use {
actix::{Actor, SyncContext},
diesel::pg::PgConnection,
diesel::r2d2::{self, ConnectionManager},
};
pub mod authorize_user;
pub mod comments;
@ -72,7 +70,8 @@ pub struct Guard<'l> {
impl<'l> Guard<'l> {
pub fn new(conn: &'l DbPooledConn) -> Result<Self, crate::DatabaseError> {
use diesel::{connection::TransactionManager, prelude::*};
use diesel::connection::TransactionManager;
use diesel::prelude::*;
let tm = conn.transaction_manager();
tm.begin_transaction(conn).map_err(|e| {
log::error!("{:?}", e);

View File

@ -1,11 +1,8 @@
use {
crate::{
db_create, db_delete, db_load,
users::{FindUser, LookupUser},
},
diesel::prelude::*,
jirs_data::{BindToken, Message, MessageId, MessageType, User, UserId},
};
use diesel::prelude::*;
use jirs_data::{BindToken, Message, MessageId, MessageType, User, UserId};
use crate::users::{FindUser, LookupUser};
use crate::{db_create, db_delete, db_load};
db_load! {
LoadMessages,

View File

@ -1,13 +1,12 @@
use {
crate::schema::*,
chrono::NaiveDateTime,
jirs_data::{
EpicId, InvitationState, IssuePriority, IssueStatusId, IssueType, ProjectCategory,
ProjectId, TimeTracking, UserId,
},
serde::{Deserialize, Serialize},
uuid::Uuid,
use chrono::NaiveDateTime;
use jirs_data::{
EpicId, InvitationState, IssuePriority, IssueStatusId, IssueType, ProjectCategory, ProjectId,
TimeTracking, UserId,
};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
use crate::schema::*;
#[derive(Serialize, Debug, Deserialize, Queryable)]
pub struct Issue {

View File

@ -1,8 +1,7 @@
use {
crate::{db_create, db_find, db_load, db_update},
diesel::prelude::*,
jirs_data::{NameString, Project, ProjectCategory, ProjectId, TimeTracking, UserId},
};
use diesel::prelude::*;
use jirs_data::{NameString, Project, ProjectCategory, ProjectId, TimeTracking, UserId};
use crate::{db_create, db_find, db_load, db_update};
db_find! {
LoadCurrentProject,
@ -12,11 +11,10 @@ db_find! {
}
mod inner {
use {
crate::db_create,
diesel::prelude::*,
jirs_data::{NameString, Project, ProjectCategory, TimeTracking},
};
use diesel::prelude::*;
use jirs_data::{NameString, Project, ProjectCategory, TimeTracking};
use crate::db_create;
db_create! {
CreateProject,

View File

@ -1,8 +1,7 @@
use {
crate::{db_create, db_find, db_update},
diesel::prelude::*,
jirs_data::{Token, UserId},
};
use diesel::prelude::*;
use jirs_data::{Token, UserId};
use crate::{db_create, db_find, db_update};
db_find! {
FindUserId,

View File

@ -1,8 +1,7 @@
use {
crate::{db_create, db_delete, db_find, db_load, db_update},
diesel::prelude::*,
jirs_data::{ProjectId, UserId, UserProject, UserProjectId, UserRole},
};
use diesel::prelude::*;
use jirs_data::{ProjectId, UserId, UserProject, UserProjectId, UserRole};
use crate::{db_create, db_delete, db_find, db_load, db_update};
db_find! {
CurrentUserProject,
@ -27,11 +26,10 @@ db_load! {
}
mod inner {
use {
crate::db_update,
diesel::prelude::*,
jirs_data::{UserId, UserProject, UserProjectId},
};
use diesel::prelude::*;
use jirs_data::{UserId, UserProject, UserProjectId};
use crate::db_update;
db_update! {
ChangeProjectIsCurrent,

View File

@ -1,11 +1,9 @@
use {
crate::{
db_create, db_find, db_load, db_update, projects::CreateProject, q,
user_projects::CreateUserProject, DbPooledConn,
},
diesel::prelude::*,
jirs_data::{EmailString, IssueId, ProjectId, User, UserId, UserRole, UsernameString},
};
use diesel::prelude::*;
use jirs_data::{EmailString, IssueId, ProjectId, User, UserId, UserRole, UsernameString};
use crate::projects::CreateProject;
use crate::user_projects::CreateUserProject;
use crate::{db_create, db_find, db_load, db_update, q, DbPooledConn};
db_find! {
FindUser,
@ -156,12 +154,10 @@ db_update! {
#[cfg(test)]
mod tests {
use diesel::connection::TransactionManager;
use jirs_data::{Project, ProjectCategory};
use crate::build_pool;
use super::*;
use crate::build_pool;
#[test]
fn check_collision() {

View File

@ -1,9 +1,9 @@
use {
actix::SyncContext,
actix_files::{self, Files},
jirs_config::fs::Configuration,
std::{io::Write, path::PathBuf},
};
use std::io::Write;
use std::path::PathBuf;
use actix::SyncContext;
use actix_files::{self, Files};
use jirs_config::fs::Configuration;
#[derive(Debug)]
pub enum FsError {

View File

@ -1,14 +1,11 @@
use {
actix::{Actor, Handler, SyncContext},
jirs_data::HighlightedCode,
simsearch::SimSearch,
std::sync::Arc,
syntect::{
easy::HighlightLines,
highlighting::{Style, ThemeSet},
parsing::SyntaxSet,
},
};
use std::sync::Arc;
use actix::{Actor, Handler, SyncContext};
use jirs_data::HighlightedCode;
use simsearch::SimSearch;
use syntect::easy::HighlightLines;
use syntect::highlighting::{Style, ThemeSet};
use syntect::parsing::SyntaxSet;
mod load;

View File

@ -1,9 +1,8 @@
use {
bincode::{deserialize_from, Result},
flate2::bufread::ZlibDecoder,
serde::de::DeserializeOwned,
std::io::BufRead,
};
use std::io::BufRead;
use bincode::{deserialize_from, Result};
use flate2::bufread::ZlibDecoder;
use serde::de::DeserializeOwned;
fn from_reader<T: DeserializeOwned, R: BufRead>(input: R) -> Result<T> {
let mut decoder = ZlibDecoder::new(input);

View File

@ -1,8 +1,7 @@
use {
crate::MailExecutor,
actix::{Handler, Message},
uuid::Uuid,
};
use actix::{Handler, Message};
use uuid::Uuid;
use crate::MailExecutor;
#[derive(Debug)]
pub struct Invite {

View File

@ -1,8 +1,7 @@
use {
crate::MailExecutor,
actix::{Handler, Message},
uuid::Uuid,
};
use actix::{Handler, Message};
use uuid::Uuid;
use crate::MailExecutor;
#[derive(Debug)]
pub struct Welcome {

View File

@ -1,19 +1,21 @@
use std::io::Write;
use actix::Addr;
use actix_multipart::{Field, Multipart};
use actix_web::http::header::ContentDisposition;
use actix_web::web::Data;
use actix_web::{post, web, Error, HttpResponse};
use database_actor::authorize_user::AuthorizeUser;
use database_actor::user_projects::CurrentUserProject;
use database_actor::users::UpdateAvatarUrl;
use database_actor::DbExecutor;
#[cfg(feature = "local-storage")]
use filesystem_actor;
use {
actix::Addr,
actix_multipart::{Field, Multipart},
actix_web::{http::header::ContentDisposition, post, web, web::Data, Error, HttpResponse},
database_actor::{
authorize_user::AuthorizeUser, user_projects::CurrentUserProject, users::UpdateAvatarUrl,
DbExecutor,
},
futures::{executor::block_on, StreamExt, TryStreamExt},
jirs_data::{User, UserId, WsMsg},
websocket_actor::server::{InnerMsg::BroadcastToChannel, WsServer},
};
use futures::executor::block_on;
use futures::{StreamExt, TryStreamExt};
use jirs_data::{User, UserId, WsMsg};
use websocket_actor::server::InnerMsg::BroadcastToChannel;
use websocket_actor::server::WsServer;
#[post("/")]
pub async fn upload(

View File

@ -1,6 +1,6 @@
use actix_web::HttpResponse;
use jirs_data::{msg::WsError, ErrorResponse};
use jirs_data::msg::WsError;
use jirs_data::ErrorResponse;
const TOKEN_NOT_FOUND: &str = "Token not found";
const DATABASE_CONNECTION_FAILED: &str = "Database connection failed";

View File

@ -1,11 +1,11 @@
use {
actix::Addr,
actix_multipart::Field,
actix_web::{http::header::ContentDisposition, web::Data, Error},
futures::StreamExt,
jirs_data::UserId,
tokio::sync::broadcast::{Receiver, Sender},
};
use actix::Addr;
use actix_multipart::Field;
use actix_web::http::header::ContentDisposition;
use actix_web::web::Data;
use actix_web::Error;
use futures::StreamExt;
use jirs_data::UserId;
use tokio::sync::broadcast::{Receiver, Sender};
#[cfg(all(feature = "local-storage", feature = "aws-s3"))]
pub(crate) async fn handle_image(

View File

@ -1,14 +1,15 @@
#[macro_use]
extern crate log;
use actix::Addr;
use actix_web::web::Data;
use actix_web::{HttpRequest, HttpResponse};
use database_actor::authorize_user::AuthorizeUser;
use database_actor::DbExecutor;
pub use errors::*;
use {
crate::middleware::authorize::token_from_headers,
actix::Addr,
actix_web::{web::Data, HttpRequest, HttpResponse},
database_actor::{authorize_user::AuthorizeUser, DbExecutor},
jirs_data::User,
};
use jirs_data::User;
use crate::middleware::authorize::token_from_headers;
pub mod avatar;
pub mod errors;

View File

@ -1,15 +1,12 @@
use {
actix_service::{Service, Transform},
actix_web::{
dev::{ServiceRequest, ServiceResponse},
http::header::{self},
http::HeaderMap,
Error,
},
futures::future::{ok, FutureExt, LocalBoxFuture, Ready},
jirs_data::User,
std::task::{Context, Poll},
};
use std::task::{Context, Poll};
use actix_service::{Service, Transform};
use actix_web::dev::{ServiceRequest, ServiceResponse};
use actix_web::http::header::{self};
use actix_web::http::HeaderMap;
use actix_web::Error;
use futures::future::{ok, FutureExt, LocalBoxFuture, Ready};
use jirs_data::User;
type Db = actix_web::web::Data<database_actor::DbPool>;

View File

@ -1,16 +1,13 @@
use {
crate::{
use actix::AsyncContext;
use database_actor::authorize_user::AuthorizeUser;
use database_actor::tokens::{CreateBindToken, FindBindToken};
use database_actor::users::LookupUser;
use futures::executor::block_on;
use jirs_data::{Token, WsMsg};
use mail_actor::welcome::Welcome;
use crate::{
db_or_debug_and_return, mail_or_debug_and_return, WebSocketActor, WsHandler, WsResult,
},
actix::AsyncContext,
database_actor::{
authorize_user::AuthorizeUser,
tokens::{CreateBindToken, FindBindToken},
users::LookupUser,
},
futures::executor::block_on,
jirs_data::{Token, WsMsg},
mail_actor::welcome::Welcome,
};
pub struct Authenticate {

View File

@ -1,8 +1,7 @@
use {
crate::{db_or_debug_and_return, WebSocketActor, WsHandler, WsResult},
futures::executor::block_on,
jirs_data::{CommentId, CreateCommentPayload, IssueId, UpdateCommentPayload, WsMsg},
};
use futures::executor::block_on;
use jirs_data::{CommentId, CreateCommentPayload, IssueId, UpdateCommentPayload, WsMsg};
use crate::{db_or_debug_and_return, WebSocketActor, WsHandler, WsResult};
pub struct LoadIssueComments {
pub issue_id: IssueId,

View File

@ -1,9 +1,7 @@
use jirs_data::IssueType;
use {
crate::{db_or_debug_and_return, WebSocketActor, WsHandler, WsResult},
futures::executor::block_on,
jirs_data::{DescriptionString, EpicId, NameString, UserProject, WsMsg},
};
use futures::executor::block_on;
use jirs_data::{DescriptionString, EpicId, IssueType, NameString, UserProject, WsMsg};
use crate::{db_or_debug_and_return, WebSocketActor, WsHandler, WsResult};
pub struct LoadEpics;
@ -60,7 +58,7 @@ impl WsHandler<UpdateEpic> for WebSocketActor {
self,
database_actor::epics::UpdateEpic {
project_id: *project_id,
epic_id: epic_id,
epic_id,
name: name.clone(),
}
);
@ -80,7 +78,7 @@ impl WsHandler<DeleteEpic> for WebSocketActor {
self,
database_actor::epics::DeleteEpic {
user_id: *user_id,
epic_id: epic_id,
epic_id,
}
);
Ok(Some(WsMsg::EpicDeleted(epic_id, n)))

View File

@ -1,8 +1,7 @@
use {
crate::{actor_or_debug_and_return, WebSocketActor, WsHandler, WsResult},
futures::executor::block_on,
jirs_data::{Code, Lang, WsMsg},
};
use futures::executor::block_on;
use jirs_data::{Code, Lang, WsMsg};
use crate::{actor_or_debug_and_return, WebSocketActor, WsHandler, WsResult};
pub struct HighlightCode(pub Lang, pub Code);

View File

@ -1,13 +1,14 @@
use {
crate::{
db_or_debug_and_return, mail_or_debug_and_return, server::InnerMsg, WebSocketActor,
WsHandler, WsMessageSender, WsResult,
},
database_actor::{invitations, messages::CreateMessageReceiver},
futures::executor::block_on,
jirs_data::{
use database_actor::invitations;
use database_actor::messages::CreateMessageReceiver;
use futures::executor::block_on;
use jirs_data::{
EmailString, InvitationId, InvitationToken, MessageType, UserRole, UsernameString, WsMsg,
},
};
use crate::server::InnerMsg;
use crate::{
db_or_debug_and_return, mail_or_debug_and_return, WebSocketActor, WsHandler, WsMessageSender,
WsResult,
};
pub struct ListInvitation;

View File

@ -1,9 +1,8 @@
use {
crate::{db_or_debug_and_return, WebSocketActor, WsHandler, WsResult},
database_actor::issue_statuses,
futures::executor::block_on,
jirs_data::{IssueStatusId, Position, TitleString, WsMsg},
};
use database_actor::issue_statuses;
use futures::executor::block_on;
use jirs_data::{IssueStatusId, Position, TitleString, WsMsg};
use crate::{db_or_debug_and_return, WebSocketActor, WsHandler, WsResult};
pub struct LoadIssueStatuses;

View File

@ -1,17 +1,15 @@
use {
crate::{db_or_debug_and_return, WebSocketActor, WsHandler, WsResult},
database_actor::{
issue_assignees::LoadAssignees,
issues::{LoadProjectIssues, UpdateIssue},
},
futures::executor::block_on,
jirs_data::{
use std::collections::HashMap;
use database_actor::issue_assignees::LoadAssignees;
use database_actor::issues::{LoadProjectIssues, UpdateIssue};
use futures::executor::block_on;
use jirs_data::{
CreateIssuePayload, IssueAssignee, IssueFieldId, IssueId, IssueStatusId, ListPosition,
PayloadVariant, WsMsg,
},
std::collections::HashMap,
};
use crate::{db_or_debug_and_return, WebSocketActor, WsHandler, WsResult};
pub struct UpdateIssueHandler {
pub id: i32,
pub field_id: IssueFieldId,

View File

@ -1,9 +1,8 @@
use {
crate::{db_or_debug_and_return, WebSocketActor, WsHandler, WsResult},
database_actor::messages,
futures::executor::block_on,
jirs_data::{MessageId, WsMsg},
};
use database_actor::messages;
use futures::executor::block_on;
use jirs_data::{MessageId, WsMsg};
use crate::{db_or_debug_and_return, WebSocketActor, WsHandler, WsResult};
pub struct LoadMessages;

View File

@ -1,7 +1,14 @@
pub use {
auth::*, comments::*, epics::*, hi::*, invitations::*, issue_statuses::*, issues::*,
messages::*, projects::*, user_projects::*, users::*,
};
pub use auth::*;
pub use comments::*;
pub use epics::*;
pub use hi::*;
pub use invitations::*;
pub use issue_statuses::*;
pub use issues::*;
pub use messages::*;
pub use projects::*;
pub use user_projects::*;
pub use users::*;
pub mod auth;
pub mod comments;

View File

@ -1,9 +1,8 @@
use {
crate::{db_or_debug_and_return, WebSocketActor, WsHandler, WsResult},
database_actor as db,
futures::executor::block_on,
jirs_data::{UpdateProjectPayload, UserProject, WsMsg},
};
use database_actor as db;
use futures::executor::block_on;
use jirs_data::{UpdateProjectPayload, UserProject, WsMsg};
use crate::{db_or_debug_and_return, WebSocketActor, WsHandler, WsResult};
impl WsHandler<UpdateProjectPayload> for WebSocketActor {
fn handle_msg(&mut self, msg: UpdateProjectPayload, _ctx: &mut Self::Context) -> WsResult {

View File

@ -1,9 +1,8 @@
use {
crate::{db_or_debug_and_return, WebSocketActor, WsHandler, WsResult},
database_actor as db,
futures::executor::block_on,
jirs_data::{UserProjectId, WsMsg},
};
use database_actor as db;
use futures::executor::block_on;
use jirs_data::{UserProjectId, WsMsg};
use crate::{db_or_debug_and_return, WebSocketActor, WsHandler, WsResult};
pub struct LoadUserProjects;

View File

@ -1,11 +1,10 @@
use {
crate::{
db_or_debug_and_return, handlers::auth::Authenticate, WebSocketActor, WsHandler, WsResult,
},
database_actor::{self, users::Register as DbRegister},
futures::executor::block_on,
jirs_data::{UserId, UserProject, UserRole, WsMsg},
};
use database_actor::users::Register as DbRegister;
use database_actor::{self};
use futures::executor::block_on;
use jirs_data::{UserId, UserProject, UserRole, WsMsg};
use crate::handlers::auth::Authenticate;
use crate::{db_or_debug_and_return, WebSocketActor, WsHandler, WsResult};
pub struct LoadProjectUsers;

View File

@ -1,24 +1,20 @@
#[macro_use]
extern crate log;
use {
crate::{
handlers::*,
server::{InnerMsg, WsServer},
},
actix::{Actor, ActorContext, Addr, AsyncContext, Handler, Recipient, StreamHandler},
actix_web::{
get,
web::{self, Data},
Error, HttpRequest, HttpResponse,
},
actix_web_actors::ws,
database_actor::{projects::LoadCurrentProject, user_projects::CurrentUserProject, DbExecutor},
futures::executor::block_on,
jirs_data::{Project, User, UserProject, WsMsg},
log::*,
mail_actor::MailExecutor,
};
use actix::{Actor, ActorContext, Addr, AsyncContext, Handler, Recipient, StreamHandler};
use actix_web::web::{self, Data};
use actix_web::{get, Error, HttpRequest, HttpResponse};
use actix_web_actors::ws;
use database_actor::projects::LoadCurrentProject;
use database_actor::user_projects::CurrentUserProject;
use database_actor::DbExecutor;
use futures::executor::block_on;
use jirs_data::{Project, User, UserProject, WsMsg};
use log::*;
use mail_actor::MailExecutor;
use crate::handlers::*;
use crate::server::{InnerMsg, WsServer};
pub mod handlers;
pub mod prelude;

View File

@ -1,8 +1,7 @@
use {
actix::{Actor, Context, Recipient},
jirs_data::{ProjectId, UserId, WsMsg},
std::collections::HashMap,
};
use std::collections::HashMap;
use actix::{Actor, Context, Recipient};
use jirs_data::{ProjectId, UserId, WsMsg};
#[derive(actix::Message, Debug)]
#[rtype(result = "()")]

View File

@ -3,11 +3,12 @@ mod utils;
extern crate proc_macro;
use {
crate::parse_attr::Attributes,
proc_macro::{token_stream::IntoIter, TokenStream, TokenTree},
std::iter::Peekable,
};
use std::iter::Peekable;
use proc_macro::token_stream::IntoIter;
use proc_macro::{TokenStream, TokenTree};
use crate::parse_attr::Attributes;
fn parse_meta(mut it: Peekable<IntoIter>) -> (Peekable<IntoIter>, Option<Attributes>) {
let mut attrs: Option<Attributes> = None;
@ -70,7 +71,6 @@ fn parse_meta(mut it: Peekable<IntoIter>) -> (Peekable<IntoIter>, Option<Attribu
/// pub name: String
/// }
/// ```
///
#[proc_macro_derive(Execute, attributes(db_exec))]
pub fn derive_enum_iter(item: TokenStream) -> TokenStream {
let mut it = item.into_iter().peekable();

View File

@ -1,6 +1,8 @@
use proc_macro::{token_stream::IntoIter, TokenTree};
use std::iter::Peekable;
use proc_macro::token_stream::IntoIter;
use proc_macro::TokenTree;
#[derive(Default, Debug)]
pub struct Attributes {
pub result: Option<String>,

View File

@ -1,6 +1,8 @@
use proc_macro::{token_stream::IntoIter, TokenTree};
use std::iter::Peekable;
use proc_macro::token_stream::IntoIter;
use proc_macro::TokenTree;
pub fn skip_pub(mut it: Peekable<IntoIter>) -> Peekable<IntoIter> {
if let Some(TokenTree::Ident(ident)) = it.next() {
if ident.to_string().as_str() != "pub" {

View File

@ -1,9 +1,9 @@
extern crate proc_macro;
use {
proc_macro::{token_stream::IntoIter, TokenStream, TokenTree},
std::iter::Peekable,
};
use std::iter::Peekable;
use proc_macro::token_stream::IntoIter;
use proc_macro::{TokenStream, TokenTree};
fn skip_meta(mut it: Peekable<IntoIter>) -> Peekable<IntoIter> {
while let Some(token) = it.peek() {

View File

@ -1,22 +1,18 @@
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,
},
};
use std::error::Error;
use std::io;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{mpsc, Arc};
use std::time::Duration;
use termion::event::Key;
use termion::input::MouseTerminal;
use termion::raw::IntoRawMode;
use termion::screen::AlternateScreen;
use tui::backend::TermionBackend;
use tui::layout::{Constraint, Direction, Layout};
use tui::style::{Color, Style};
use tui::widgets::{Block, Borders, Tabs};
use tui::Terminal;
#[derive(Debug, Clone, Copy)]
pub struct Config {
@ -68,8 +64,8 @@ impl Events {
// eprintln!("{}", err);
// return;
// }
// if !ignore_exit_key.load(Ordering::Relaxed) && key == config.exit_key {
// return;
// if !ignore_exit_key.load(Ordering::Relaxed) && key ==
// config.exit_key { return;
// }
// }
// }
@ -84,8 +80,8 @@ impl Events {
Events {
rx,
ignore_exit_key,
// input_handle,
// tick_handle,
/* input_handle,
* tick_handle, */
}
}

View File

@ -1,8 +1,8 @@
use {
crate::{components::styled_editor::Mode as TabMode, FieldId},
jirs_data::{EpicId, IssueStatusId, WsMsg},
seed::prelude::WebSocketMessage,
};
use jirs_data::{EpicId, IssueStatusId, WsMsg};
use seed::prelude::WebSocketMessage;
use crate::components::styled_editor::Mode as TabMode;
use crate::FieldId;
#[derive(Clone, Debug, PartialEq)]
pub enum FieldChange {

View File

@ -1,7 +1,8 @@
use {
crate::{shared::ToNode, Msg},
seed::{prelude::*, *},
};
use seed::prelude::*;
use seed::*;
use crate::shared::ToNode;
use crate::Msg;
#[derive(Debug)]
pub struct StyledAvatar<'l> {

View File

@ -1,7 +1,8 @@
use {
crate::{shared::ToNode, ButtonId, Msg},
seed::{prelude::*, *},
};
use seed::prelude::*;
use seed::*;
use crate::shared::ToNode;
use crate::{ButtonId, Msg};
#[allow(dead_code)]
pub enum ButtonVariant {

View File

@ -1,11 +1,8 @@
use {
crate::{
shared::{IntoChild, ToNode},
FieldId, Msg,
},
jirs_data::TimeTracking,
seed::{prelude::*, *},
};
use seed::prelude::*;
use seed::*;
use crate::shared::ToNode;
use crate::{FieldId, Msg};
#[derive(Debug)]
pub struct StyledCheckboxState {
@ -30,12 +27,12 @@ impl StyledCheckboxState {
#[derive(Debug)]
pub struct ChildBuilder<'l> {
field_id: Option<FieldId>,
name: &'l str,
label: &'l str,
value: u32,
selected: bool,
class_list: Vec<String>,
pub field_id: Option<FieldId>,
pub name: &'l str,
pub label: &'l str,
pub value: u32,
pub selected: bool,
pub class_list: &'l str,
}
impl<'l> Default for ChildBuilder<'l> {
@ -46,7 +43,7 @@ impl<'l> Default for ChildBuilder<'l> {
label: "",
value: 0,
selected: false,
class_list: vec![],
class_list: "",
}
}
}
@ -77,11 +74,8 @@ impl<'l> ChildBuilder<'l> {
self
}
pub fn add_class<S>(mut self, name: S) -> Self
where
S: Into<String>,
{
self.class_list.push(name.into());
pub fn class_list(mut self, name: &'l str) -> Self {
self.class_list = name;
self
}
}
@ -94,7 +88,7 @@ impl<'l> ToNode for ChildBuilder<'l> {
label,
value,
selected,
mut class_list,
class_list,
} = self;
let id = field_id.as_ref().map(|f| f.to_string()).unwrap_or_default();
@ -103,9 +97,6 @@ impl<'l> ToNode for ChildBuilder<'l> {
field_id_clone.map(|field_id| Msg::U32InputChanged(field_id, value))
});
class_list.push("styledCheckboxChild".to_string());
class_list.push(if selected { "selected" } else { "" }.to_string());
let input_attrs = if selected {
attrs![At::Type => "radio", At::Name => name, At::Checked => selected, At::Id => format!("{}-{}", id, name)]
} else {
@ -113,7 +104,11 @@ impl<'l> ToNode for ChildBuilder<'l> {
};
div![
attrs![At::Class => class_list.join(" ")],
C![
"styledCheckboxChild",
class_list,
IF![selected => "selected"]
],
handler,
label![attrs![At::For => format!("{}-{}", id, name)], label],
input![input_attrs],
@ -216,27 +211,3 @@ where
opt,
]
}
impl<'l> IntoChild<'l> for TimeTracking {
type Builder = ChildBuilder<'l>;
fn into_child(self) -> Self::Builder {
Self::Builder::default()
.label(match self {
TimeTracking::Untracked => "No tracking",
TimeTracking::Fibonacci => "Fibonacci (Bad mode)",
TimeTracking::Hourly => "Evil Mode (Hourly)",
})
.name(match self {
TimeTracking::Untracked => "untracked",
TimeTracking::Fibonacci => "fibonacci",
TimeTracking::Hourly => "hourly",
})
.add_class(match self {
TimeTracking::Untracked => "untracked",
TimeTracking::Fibonacci => "fibonacci",
TimeTracking::Hourly => "hourly",
})
.value((self).into())
}
}

View File

@ -1,13 +1,10 @@
use {
crate::{
components::{styled_button::StyledButton, styled_modal::StyledModal},
shared::ToNode,
Msg,
},
seed::{prelude::*, EventHandler, *},
};
use seed::prelude::*;
use seed::{EventHandler, *};
use crate::components::styled_button::ButtonVariant;
use crate::components::styled_button::{ButtonVariant, StyledButton};
use crate::components::styled_modal::StyledModal;
use crate::shared::ToNode;
use crate::Msg;
const TITLE: &str = "Warning";
const MESSAGE: &str = "Are you sure you want to continue with this action?";

View File

@ -1,19 +1,15 @@
use {
crate::{
components::{
styled_button::StyledButton, styled_icon::Icon, styled_tooltip::StyledTooltip,
},
shared::ToNode,
FieldId, Msg,
},
chrono::prelude::*,
chrono::Duration,
seed::{prelude::*, *},
std::ops::RangeInclusive,
};
use std::ops::RangeInclusive;
use crate::components::styled_button::ButtonVariant;
use crate::components::styled_tooltip::TooltipVariant;
use chrono::prelude::*;
use chrono::Duration;
use seed::prelude::*;
use seed::*;
use crate::components::styled_button::{ButtonVariant, StyledButton};
use crate::components::styled_icon::Icon;
use crate::components::styled_tooltip::{StyledTooltip, TooltipVariant};
use crate::shared::ToNode;
use crate::{FieldId, Msg};
#[derive(Debug)]
pub enum StyledDateTimeChanged {

View File

@ -1,9 +1,9 @@
use {
crate::{
components::styled_textarea::StyledTextarea, shared::ToNode, FieldChange, FieldId, Msg,
},
seed::{prelude::*, *},
};
use seed::prelude::*;
use seed::*;
use crate::components::styled_textarea::StyledTextarea;
use crate::shared::ToNode;
use crate::{FieldChange, FieldId, Msg};
#[derive(Debug, Clone, PartialOrd, PartialEq, Hash)]
pub enum Mode {

View File

@ -1,7 +1,8 @@
use {
crate::{shared::ToNode, Msg},
seed::{prelude::*, *},
};
use seed::prelude::*;
use seed::*;
use crate::shared::ToNode;
use crate::Msg;
#[derive(Debug)]
pub struct StyledField<'l> {
@ -22,57 +23,12 @@ impl<'l> Default for StyledField<'l> {
}
}
impl<'l> StyledField<'l> {
pub fn build() -> StyledFieldBuilder<'l> {
StyledFieldBuilder::default()
}
}
impl<'l> ToNode for StyledField<'l> {
fn into_node(self) -> Node<Msg> {
render(self)
}
}
#[derive(Default, Debug)]
pub struct StyledFieldBuilder<'l> {
label: Option<&'l str>,
tip: Option<&'l str>,
input: Option<Node<Msg>>,
class_list: &'l str,
}
impl<'l> StyledFieldBuilder<'l> {
pub fn label(mut self, label: &'l str) -> Self {
self.label = Some(label);
self
}
pub fn tip(mut self, tip: &'l str) -> Self {
self.tip = Some(tip);
self
}
pub fn input(mut self, input: Node<Msg>) -> Self {
self.input = Some(input);
self
}
pub fn class_list(mut self, name: &'l str) -> Self {
self.class_list = name;
self
}
pub fn build(self) -> StyledField<'l> {
StyledField {
label: self.label.unwrap_or_default(),
tip: self.tip,
input: self.input.unwrap_or(empty![]),
class_list: self.class_list,
}
}
}
pub fn render(values: StyledField) -> Node<Msg> {
let StyledField {
label,

View File

@ -1,7 +1,8 @@
use {
crate::{shared::ToNode, Msg},
seed::{prelude::*, *},
};
use seed::prelude::*;
use seed::*;
use crate::shared::ToNode;
use crate::Msg;
#[derive(Debug, Clone)]
pub struct StyledForm<'l> {

View File

@ -1,9 +1,11 @@
use {
crate::{shared::ToNode, Msg},
jirs_data::{IssuePriority, IssueType},
seed::{prelude::*, *},
std::borrow::Cow,
};
use std::borrow::Cow;
use jirs_data::{IssuePriority, IssueType};
use seed::prelude::*;
use seed::*;
use crate::shared::ToNode;
use crate::Msg;
#[allow(dead_code)]
#[derive(Copy, Clone, Debug)]
@ -245,37 +247,6 @@ impl ToNode for Icon {
}
}
pub struct StyledIconBuilder<'l> {
pub icon: Icon,
pub size: Option<i32>,
pub class_list: &'l str,
pub style_list: Vec<Cow<'l, str>>,
pub color: Option<Cow<'l, str>>,
pub on_click: Option<EventHandler<Msg>>,
}
impl<'l> StyledIconBuilder<'l> {
pub fn size(mut self, size: i32) -> Self {
self.size = Some(size);
self
}
pub fn class_list(mut self, name: &'l str) -> Self {
self.class_list = name;
self
}
pub fn with_color(mut self, color: &'l str) -> Self {
self.color = Some(Cow::Borrowed(color));
self
}
pub fn on_click(mut self, on_click: EventHandler<Msg>) -> Self {
self.on_click = Some(on_click);
self
}
}
pub struct StyledIcon<'l> {
pub icon: Icon,
pub size: Option<i32>,

View File

@ -1,8 +1,9 @@
use {
crate::{shared::ToNode, FieldId, Msg},
seed::{prelude::*, *},
web_sys::File,
};
use seed::prelude::*;
use seed::*;
use web_sys::File;
use crate::shared::ToNode;
use crate::{FieldId, Msg};
#[derive(Debug, Clone)]
pub struct StyledImageInputState {

View File

@ -1,11 +1,9 @@
use {
crate::{
components::styled_icon::{Icon, StyledIcon},
shared::ToNode,
FieldId, Msg,
},
seed::{prelude::*, *},
};
use seed::prelude::*;
use seed::*;
use crate::components::styled_icon::{Icon, StyledIcon};
use crate::shared::ToNode;
use crate::{FieldId, Msg};
#[derive(Clone, Debug, PartialOrd, PartialEq)]
pub enum InputVariant {

View File

@ -1,8 +1,10 @@
use {
crate::{shared::ToNode, Msg},
seed::{prelude::*, *},
std::str::FromStr,
};
use std::str::FromStr;
use seed::prelude::*;
use seed::*;
use crate::shared::ToNode;
use crate::Msg;
pub struct StyledLink<'l> {
pub children: Vec<Node<Msg>>,
@ -10,48 +12,6 @@ pub struct StyledLink<'l> {
pub href: &'l str,
}
impl<'l> StyledLink<'l> {
// pub fn build() -> StyledLinkBuilder<'l> {
// StyledLinkBuilder::default()
// }
}
#[derive(Default)]
pub struct StyledLinkBuilder<'l> {
children: Vec<Node<Msg>>,
class_list: &'l str,
href: &'l str,
}
impl<'l> StyledLinkBuilder<'l> {
pub fn add_child(mut self, child: Node<Msg>) -> Self {
self.children.push(child);
self
}
pub fn class_list(mut self, name: &'l str) -> Self {
self.class_list = name;
self
}
pub fn href(mut self, href: &'l str) -> Self {
self.href = href;
self
}
pub fn text(self, s: &'l str) -> Self {
self.add_child(span![s])
}
pub fn build(self) -> StyledLink<'l> {
StyledLink {
children: self.children,
class_list: self.class_list,
href: self.href,
}
}
}
impl<'l> ToNode for StyledLink<'l> {
fn into_node(self) -> Node<Msg> {
render(self)

View File

@ -1,11 +1,9 @@
use {
crate::{
components::styled_icon::{Icon, StyledIcon},
shared::ToNode,
Msg,
},
seed::{prelude::*, *},
};
use seed::prelude::*;
use seed::*;
use crate::components::styled_icon::{Icon, StyledIcon};
use crate::shared::ToNode;
use crate::Msg;
#[allow(dead_code)]
#[derive(Debug, Copy, Clone, PartialOrd, PartialEq)]

View File

@ -1,14 +1,12 @@
use {
crate::{
components::{
styled_icon::{Icon, StyledIcon},
styled_select_child::*,
},
shared::ToNode,
FieldId, Msg,
},
seed::{prelude::*, *},
};
use std::collections::HashMap;
use seed::prelude::*;
use seed::*;
use crate::components::styled_icon::{Icon, StyledIcon};
use crate::components::styled_select_child::*;
use crate::shared::ToNode;
use crate::{FieldId, Msg};
#[derive(Clone, Debug, PartialEq)]
pub enum StyledSelectChanged {
@ -71,7 +69,7 @@ impl StyledSelectState {
}
}
pub fn update(&mut self, msg: &Msg, _orders: &mut impl Orders<Msg>) {
pub fn update(&mut self, msg: &Msg, orders: &mut impl Orders<Msg>) {
let field_id = match msg {
Msg::StyledSelectChanged(field_id, ..) => field_id,
_ => return,
@ -87,6 +85,7 @@ impl StyledSelectState {
}
}
Msg::StyledSelectChanged(_, StyledSelectChanged::Text(text)) => {
orders.skip();
self.text_filter = text.clone();
}
Msg::StyledSelectChanged(_, StyledSelectChanged::Changed(Some(v))) => {
@ -112,7 +111,7 @@ impl StyledSelectState {
pub struct StyledSelect<'l, Options>
where
Options: Iterator<Item = StyledSelectChildBuilder<'l>>,
Options: Iterator<Item = StyledSelectChild<'l>>,
{
pub id: FieldId,
pub variant: SelectVariant,
@ -121,7 +120,7 @@ where
pub valid: bool,
pub is_multi: bool,
pub options: Option<Options>,
pub selected: Vec<StyledSelectChildBuilder<'l>>,
pub selected: Vec<StyledSelectChild<'l>>,
pub text_filter: &'l str,
pub opened: bool,
pub clearable: bool,
@ -129,7 +128,7 @@ where
impl<'l, Options> Default for StyledSelect<'l, Options>
where
Options: Iterator<Item = StyledSelectChildBuilder<'l>>,
Options: Iterator<Item = StyledSelectChild<'l>>,
{
fn default() -> Self {
Self {
@ -150,7 +149,7 @@ where
impl<'l, Options> ToNode for StyledSelect<'l, Options>
where
Options: Iterator<Item = StyledSelectChildBuilder<'l>>,
Options: Iterator<Item = StyledSelectChild<'l>>,
{
fn into_node(self) -> Node<Msg> {
render(self)
@ -159,7 +158,7 @@ where
pub fn render<'l, Options>(values: StyledSelect<'l, Options>) -> Node<Msg>
where
Options: Iterator<Item = StyledSelectChildBuilder<'l>>,
Options: Iterator<Item = StyledSelectChild<'l>>,
{
let StyledSelect {
id,
@ -221,13 +220,16 @@ where
empty![]
};
let skip = selected.iter().fold(HashMap::new(), |mut h, o| {
h.insert(o.value, true);
h
});
let children: Vec<Node<Msg>> = if let Some(options) = options {
options
.filter(|o| !selected.contains(&o) && o.match_text(text_filter))
.filter(|o| !skip.contains_key(&o.value) && o.match_text(text_filter))
.map(|child| {
let child = child.build(DisplayType::SelectOption);
let value = child.value();
let node = child.into_node();
let node = child.render_option();
let on_change = {
let field_id = id.clone();
@ -245,21 +247,6 @@ where
vec![]
};
let text_input = if opened {
seed::input![
C!["dropDownInput"],
attrs![
At::Name => name,
At::Type => "text"
At::Placeholder => "Search"
At::AutoFocus => "true",
],
on_text,
]
} else {
empty![]
};
let option_list = match (opened, children.is_empty()) {
(false, _) => empty![],
(_, true) => seed::div![C!["noOptions"], "No results"],
@ -281,10 +268,7 @@ where
vec![div![C!["valueMulti"], children]]
} else {
selected
.into_iter()
.map(|m| render_value(m.build(DisplayType::SelectValue).into_node()))
.collect()
selected.into_iter().map(|m| m.render_value()).collect()
};
seed::div![
@ -303,29 +287,25 @@ where
div![
C!["dropDown"],
attrs![At::Style => dropdown_style.as_str()],
text_input,
IF![opened => seed::input![
C!["dropDownInput"],
attrs![
At::Name => name,
At::Type => "text"
At::Placeholder => "Search"
At::AutoFocus => "true",
],
on_text,
]],
option_list
]
]
}
fn render_value(mut content: Node<Msg>) -> Node<Msg> {
content.add_class("value");
content
}
fn into_multi_value(opt: StyledSelectChildBuilder, id: FieldId) -> Node<Msg> {
let close_icon = StyledIcon {
icon: Icon::Close,
size: Some(14),
..Default::default()
}
.into_node();
let child = opt.build(DisplayType::SelectValue);
fn into_multi_value(child: StyledSelectChild, id: FieldId) -> Node<Msg> {
let value = child.value();
let mut opt = child.into_node();
opt.add_class("value").add_child(close_icon);
let opt = child.render_multi_value();
let handler = {
let field_id = id;

View File

@ -1,25 +1,23 @@
use {
crate::{
components::styled_select::SelectVariant,
shared::{IntoChild, ToChild, ToNode},
Msg,
},
seed::{prelude::*, *},
};
use seed::prelude::*;
use seed::*;
use crate::components::styled_avatar::StyledAvatar;
use crate::components::styled_icon::StyledIcon;
use crate::components::styled_icon::{Icon, StyledIcon};
use crate::components::styled_select::SelectVariant;
use crate::shared::ToNode;
use crate::Msg;
#[derive(Copy, Clone, PartialEq)]
#[repr(u8)]
pub enum DisplayType {
SelectOption,
SelectValue,
SelectMultiValue,
}
pub struct StyledSelectChild<'l> {
pub name: Option<&'l str>,
pub icon: Option<Node<Msg>>,
pub text: Option<&'l str>,
pub display_type: DisplayType,
pub value: u32,
pub class_list: &'l str,
pub variant: SelectVariant,
@ -31,7 +29,6 @@ impl<'l> Default for StyledSelectChild<'l> {
name: None,
icon: None,
text: None,
display_type: DisplayType::SelectOption,
value: 0,
class_list: "",
variant: Default::default(),
@ -44,95 +41,37 @@ impl<'l> StyledSelectChild<'l> {
pub fn value(&self) -> u32 {
self.value
}
}
impl<'l> ToNode for StyledSelectChild<'l> {
fn into_node(self) -> Node<Msg> {
render(self)
}
}
#[derive(Debug)]
pub struct StyledSelectChildBuilder<'l> {
pub icon: Option<Node<Msg>>,
pub text: Option<&'l str>,
pub name: Option<&'l str>,
pub value: u32,
pub class_list: &'l str,
pub variant: SelectVariant,
}
impl<'l> Default for StyledSelectChildBuilder<'l> {
fn default() -> Self {
Self {
icon: None,
text: None,
name: None,
value: 0,
class_list: "",
variant: Default::default(),
}
}
}
impl<'l> PartialEq for StyledSelectChildBuilder<'l> {
fn eq(&self, other: &Self) -> bool {
self.value == other.value
}
}
impl<'l> StyledSelectChildBuilder<'l> {
pub fn icon(mut self, icon: Node<Msg>) -> Self {
self.icon = Some(icon);
self
#[inline(always)]
pub fn render_value(self) -> Node<Msg> {
render(DisplayType::SelectValue, self)
}
pub fn text<'m: 'l>(mut self, text: &'m str) -> Self {
self.text = Some(text);
self
#[inline(always)]
pub fn render_multi_value(self) -> Node<Msg> {
render(DisplayType::SelectMultiValue, self)
}
pub fn name(mut self, name: &'l str) -> Self {
self.name = Some(name);
self
}
pub fn value(mut self, value: u32) -> Self {
self.value = value;
self
#[inline(always)]
pub fn render_option(self) -> Node<Msg> {
render(DisplayType::SelectOption, self)
}
#[inline(always)]
pub fn match_text(&self, text: &str) -> bool {
self.text
.as_ref()
.map(|t| t.to_lowercase().contains(text.to_lowercase().as_str()))
.unwrap_or(true)
}
pub fn class_list<'m: 'l>(mut self, name: &'m str) -> Self {
self.class_list = name;
self
}
pub fn build(self, display_type: DisplayType) -> StyledSelectChild<'l> {
StyledSelectChild {
name: self.name,
icon: self.icon,
text: self.text,
display_type,
value: self.value,
class_list: self.class_list,
variant: self.variant,
}
}
}
pub fn render(values: StyledSelectChild) -> Node<Msg> {
#[inline(always)]
pub fn render(display_type: DisplayType, values: StyledSelectChild) -> Node<Msg> {
let StyledSelectChild {
name,
icon,
text,
display_type,
value: _,
class_list,
variant,
@ -152,7 +91,7 @@ pub fn render(values: StyledSelectChild) -> Node<Msg> {
.unwrap_or_default(),
match display_type {
DisplayType::SelectOption => "optionLabel",
DisplayType::SelectValue => "selectItemLabel",
DisplayType::SelectValue | DisplayType::SelectMultiValue => "selectItemLabel",
},
class_list
],
@ -167,168 +106,22 @@ pub fn render(values: StyledSelectChild) -> Node<Msg> {
name.as_deref().unwrap_or_default(),
match display_type {
DisplayType::SelectOption => "optionItem",
DisplayType::SelectValue => "selectItem",
DisplayType::SelectValue | DisplayType::SelectMultiValue => "selectItem value",
},
class_list
],
icon_node,
label_node
label_node,
IF![display_type == DisplayType::SelectMultiValue => close_icon()]
]
}
impl<'l> ToChild<'l> for jirs_data::User {
type Builder = StyledSelectChildBuilder<'l>;
fn to_child<'m: 'l>(&'m self) -> Self::Builder {
let avatar = StyledAvatar {
size: 20,
name: &self.name,
avatar_url: self.avatar_url.as_deref(),
..StyledAvatar::default()
}
.into_node();
StyledSelectChildBuilder {
value: self.id as u32,
icon: Some(avatar),
text: Some(self.name.as_str()),
#[inline(always)]
fn close_icon() -> Node<Msg> {
StyledIcon {
icon: Icon::Close,
size: Some(14),
..Default::default()
}
}
}
impl<'l> IntoChild<'l> for jirs_data::IssuePriority {
type Builder = StyledSelectChildBuilder<'l>;
fn into_child(self) -> Self::Builder {
let icon = StyledIcon {
icon: self.clone().into(),
class_list: self.to_str(),
..Default::default()
}
.into_node();
StyledSelectChildBuilder {
icon: Some(icon),
text: Some(self.to_str()),
class_list: self.to_str(),
value: self.into(),
..Default::default()
}
}
}
impl<'l> ToChild<'l> for jirs_data::IssueStatus {
type Builder = StyledSelectChildBuilder<'l>;
fn to_child<'m: 'l>(&'m self) -> Self::Builder {
StyledSelectChildBuilder {
value: self.id as u32,
class_list: self.name.as_str(),
text: Some(self.name.as_str()),
..Default::default()
}
}
}
impl<'l> IntoChild<'l> for jirs_data::IssueType {
type Builder = StyledSelectChildBuilder<'l>;
fn into_child(self) -> Self::Builder {
let name = self.to_label();
let type_icon = StyledIcon {
icon: self.clone().into(),
class_list: name,
..Default::default()
}
.into_node();
StyledSelectChildBuilder {
class_list: name,
text: Some(name),
icon: Some(type_icon),
value: self.into(),
..Default::default()
}
}
}
impl<'l> IntoChild<'l> for jirs_data::ProjectCategory {
type Builder = StyledSelectChildBuilder<'l>;
fn into_child(self) -> Self::Builder {
StyledSelectChildBuilder {
class_list: self.to_str(),
text: Some(self.to_str()),
value: self.into(),
..Default::default()
}
}
}
impl<'l> IntoChild<'l> for jirs_data::UserRole {
type Builder = StyledSelectChildBuilder<'l>;
fn into_child(self) -> Self::Builder {
let name = self.to_str();
StyledSelectChildBuilder {
text: Some(name),
value: self.into(),
class_list: name,
..Default::default()
}
}
}
macro_rules! id_name_builder {
() => {
fn to_child<'m: 'l>(&'m self) -> Self::Builder {
StyledSelectChildBuilder {
text: Some(self.name.as_str()),
value: self.id as u32,
..Default::default()
}
}
};
}
impl<'l> ToChild<'l> for jirs_data::Project {
type Builder = StyledSelectChildBuilder<'l>;
id_name_builder!();
}
impl<'l> ToChild<'l> for jirs_data::Epic {
type Builder = StyledSelectChildBuilder<'l>;
id_name_builder!();
}
impl<'l> ToChild<'l> for u32 {
type Builder = StyledSelectChildBuilder<'l>;
fn to_child<'m: 'l>(&'m self) -> Self::Builder {
let name = stringify!(self);
StyledSelectChildBuilder {
class_list: name,
text: Some(name),
value: *self,
..Default::default()
}
}
}
pub type Label = String;
pub type Value = u32;
impl<'l> ToChild<'l> for (Label, Value) {
type Builder = StyledSelectChildBuilder<'l>;
fn to_child<'m: 'l>(&'m self) -> Self::Builder {
StyledSelectChildBuilder {
text: Some(self.0.as_str()),
value: self.1,
..Default::default()
}
}
.into_node()
}

View File

@ -1,7 +1,8 @@
use {
crate::{shared::ToNode, FieldId, Msg},
seed::{prelude::*, *},
};
use seed::prelude::*;
use seed::*;
use crate::shared::ToNode;
use crate::{FieldId, Msg};
#[derive(Debug)]
pub struct StyledTextarea<'l> {
@ -43,8 +44,8 @@ const PADDING_TOP_BOTTOM: f64 = 17f64;
const BORDER_TOP_BOTTOM: f64 = 2f64;
const ADDITIONAL_HEIGHT: f64 = PADDING_TOP_BOTTOM + BORDER_TOP_BOTTOM;
// height = `calc( (${$0.value.split("\n").length}px * ( 15 * 1.4285 )) + 17px + 2px)`
// where:
// height = `calc( (${$0.value.split("\n").length}px * ( 15 * 1.4285 )) + 17px +
// 2px)` where:
// * 15 is font-size
// * 1.4285 is line-height
// * 17 is padding top + bottom

View File

@ -1,7 +1,8 @@
use {
crate::{shared::ToNode, Msg},
seed::{prelude::*, *},
};
use seed::prelude::*;
use seed::*;
use crate::shared::ToNode;
use crate::Msg;
#[derive(Debug, Copy, Clone)]
pub enum TooltipVariant {

View File

@ -1,7 +1,7 @@
use {
crate::Msg,
seed::{prelude::*, *},
};
use seed::prelude::*;
use seed::*;
use crate::Msg;
#[inline(always)]
pub fn render() -> Node<Msg> {

View File

@ -1,22 +1,21 @@
#![feature(type_ascription, trait_alias, drain_filter)]
use {
crate::{
components::{
styled_date_time_input::StyledDateTimeChanged,
styled_select::StyledSelectChanged,
styled_tooltip,
styled_tooltip::{TooltipVariant as StyledTooltip, TooltipVariant},
},
model::{ModalType, Model, Page},
shared::{go_to_board, go_to_login},
ws::{flush_queue, open_socket, read_incoming, send_ws_msg},
},
jirs_data::*,
seed::{prelude::*, *},
web_sys::File,
};
pub use {changes::*, components::*, fields::*, images::*};
pub use changes::*;
pub use components::*;
pub use fields::*;
pub use images::*;
use jirs_data::*;
use seed::prelude::*;
use seed::*;
use web_sys::File;
use crate::components::styled_date_time_input::StyledDateTimeChanged;
use crate::components::styled_select::StyledSelectChanged;
use crate::components::styled_tooltip;
use crate::components::styled_tooltip::{TooltipVariant as StyledTooltip, TooltipVariant};
use crate::model::{ModalType, Model, Page};
use crate::shared::{go_to_board, go_to_login};
use crate::ws::{flush_queue, open_socket, read_incoming, send_ws_msg};
// use crate::shared::styled_rte::RteMsg;

View File

@ -1,4 +1,5 @@
pub use {model::*, view::*};
pub use model::*;
pub use view::*;
mod model;
mod view;

View File

@ -1,8 +1,9 @@
use {
crate::{model, shared::ToNode, styled_confirm_modal::StyledConfirmModal, Msg},
jirs_data::CommentId,
seed::prelude::*,
};
use jirs_data::CommentId;
use seed::prelude::*;
use crate::shared::ToNode;
use crate::styled_confirm_modal::StyledConfirmModal;
use crate::{model, Msg};
pub fn view(_model: &model::Model, modal: &super::Model) -> Node<Msg> {
let comment_id: CommentId = modal.comment_id;

View File

@ -1,4 +1,6 @@
pub use {model::*, update::*, view::*};
pub use model::*;
pub use update::*;
pub use view::*;
mod model;
mod update;

View File

@ -1,7 +1,10 @@
use {
crate::{components::styled_modal::StyledModal, model::Model, shared::ToNode, Msg},
seed::{prelude::*, *},
};
use seed::prelude::*;
use seed::*;
use crate::components::styled_modal::StyledModal;
use crate::model::Model;
use crate::shared::ToNode;
use crate::Msg;
pub fn view(model: &Model) -> Node<Msg> {
let text = format!("{:#?}", model);

View File

@ -1,15 +1,12 @@
use {
crate::{
components::{styled_field::StyledField, styled_select::StyledSelect},
model::{IssueModal, Model},
shared::{ToChild, ToNode},
FieldId, Msg,
},
jirs_data::EpicId,
seed::prelude::Node,
};
use jirs_data::{Epic, EpicId};
use seed::prelude::Node;
use crate::components::styled_select::SelectVariant;
use crate::components::styled_field::StyledField;
use crate::components::styled_select::{SelectVariant, StyledSelect};
use crate::components::styled_select_child::StyledSelectChild;
use crate::model::{IssueModal, Model};
use crate::shared::ToNode;
use crate::{FieldId, Msg};
pub fn epic_field<Modal>(model: &Model, modal: &Modal, field_id: FieldId) -> Option<Node<Msg>>
where
@ -18,16 +15,15 @@ where
if model.epics.is_empty() {
return None;
}
let selected = modal
.epic_id_value()
.and_then(|id| model.epics.iter().find(|epic| epic.id == id as EpicId))
.map(|epic| vec![epic.to_child()])
.unwrap_or_default();
let input = StyledSelect {
id: field_id,
name: "epic",
selected,
options: Some(model.epics.iter().map(|epic| epic.to_child())),
selected: vec![modal
.epic_id_value()
.and_then(|id| model.epics.iter().find(|epic| epic.id == id as EpicId))
.map(epic_select_option)
.unwrap_or_default()],
options: Some(model.epics.iter().map(epic_select_option)),
variant: SelectVariant::Normal,
clearable: true,
text_filter: modal.epic_state().text_filter.as_str(),
@ -46,3 +42,11 @@ where
.into_node(),
)
}
fn epic_select_option<'l>(epic: &'l Epic) -> StyledSelectChild<'l> {
StyledSelectChild {
value: epic.id as u32,
text: Some(epic.name.as_str()),
..Default::default()
}
}

View File

@ -1,4 +1,6 @@
pub use {model::*, update::*, view::*};
pub use model::*;
pub use update::*;
pub use view::*;
mod model;
mod update;

View File

@ -1,7 +1,6 @@
use {
crate::model,
jirs_data::{EpicId, IssueId},
};
use jirs_data::{EpicId, IssueId};
use crate::model;
#[derive(Clone, Debug, PartialOrd, PartialEq)]
pub struct Model {

View File

@ -1,8 +1,8 @@
use {
crate::{ws::send_ws_msg, Msg, OperationKind, ResourceKind},
jirs_data::WsMsg,
seed::prelude::*,
};
use jirs_data::WsMsg;
use seed::prelude::*;
use crate::ws::send_ws_msg;
use crate::{Msg, OperationKind, ResourceKind};
pub fn update(msg: &Msg, model: &mut crate::model::Model, orders: &mut impl Orders<Msg>) {
let modal = match &mut model.modals_mut().delete_epic {

View File

@ -1,13 +1,13 @@
use {
crate::{
components::{styled_button::*, styled_confirm_modal::*, styled_icon::*, styled_modal::*},
modals::epics_delete::Model,
model,
shared::ToNode,
Msg,
},
seed::{prelude::*, *},
};
use seed::prelude::*;
use seed::*;
use crate::components::styled_button::*;
use crate::components::styled_confirm_modal::*;
use crate::components::styled_icon::*;
use crate::components::styled_modal::*;
use crate::modals::epics_delete::Model;
use crate::shared::ToNode;
use crate::{model, Msg};
pub fn view(model: &model::Model, modal: &Model) -> Node<Msg> {
if modal.related_issues.is_empty() {

View File

@ -1,4 +1,6 @@
pub use {model::*, update::*, view::*};
pub use model::*;
pub use update::*;
pub use view::*;
mod model;
mod update;

View File

@ -1,11 +1,9 @@
use {
crate::{
components::{styled_checkbox::StyledCheckboxState, styled_input::*},
model, FieldId, Msg,
},
jirs_data::*,
seed::prelude::Orders,
};
use jirs_data::*;
use seed::prelude::Orders;
use crate::components::styled_checkbox::StyledCheckboxState;
use crate::components::styled_input::*;
use crate::{model, FieldId, Msg};
#[derive(Debug)]
pub struct Model {

View File

@ -1,8 +1,7 @@
use {
crate::{send_ws_msg, FieldId, Msg, OperationKind, ResourceKind},
jirs_data::{EpicFieldId, IssueType, WsMsg},
seed::prelude::*,
};
use jirs_data::{EpicFieldId, IssueType, WsMsg};
use seed::prelude::*;
use crate::{send_ws_msg, FieldId, Msg, OperationKind, ResourceKind};
pub fn update(msg: &Msg, model: &mut crate::model::Model, orders: &mut impl Orders<Msg>) {
let modal = match &mut model.modals.edit_epic {

View File

@ -1,17 +1,15 @@
use {
crate::{
components::{
styled_button::*, styled_checkbox::*, styled_icon::Icon, styled_input::*,
styled_modal::*,
},
modals::epics_edit::Model,
model,
shared::{IntoChild, ToNode},
FieldId, Msg,
},
jirs_data::{EpicFieldId, IssueType},
seed::{prelude::*, *},
};
use jirs_data::{EpicFieldId, IssueType};
use seed::prelude::*;
use seed::*;
use crate::components::styled_button::*;
use crate::components::styled_checkbox::*;
use crate::components::styled_icon::Icon;
use crate::components::styled_input::*;
use crate::components::styled_modal::*;
use crate::modals::epics_edit::Model;
use crate::shared::{IntoChild, ToNode};
use crate::{model, FieldId, Msg};
pub struct IssueTypeWrapper(IssueType);
@ -23,7 +21,7 @@ impl<'l> IntoChild<'l> for IssueTypeWrapper {
.label(self.0.to_label())
.name(self.0.to_str())
.value(self.0.into())
.add_class(self.0.to_str())
.class_list(self.0.to_str())
}
}
@ -68,7 +66,7 @@ fn transform_into_available(modal: &super::Model) -> Node<Msg> {
.options(
IssueType::default()
.into_iter()
.map(|ty| IssueTypeWrapper(ty).into_child()),
.map(issue_type_select_option),
)
.state(&modal.transform_into)
.build(FieldId::EditEpic(EpicFieldId::TransformInto))
@ -86,6 +84,17 @@ fn transform_into_available(modal: &super::Model) -> Node<Msg> {
div![C!["transform available"], div![types], div![execute]]
}
#[inline(always)]
fn issue_type_select_option<'l>(ty: IssueType) -> ChildBuilder<'l> {
ChildBuilder {
name: ty.to_str(),
label: ty.to_label(),
value: ty.into(),
class_list: ty.to_str(),
..Default::default()
}
}
fn transform_into_unavailable(modal: &super::Model) -> Node<Msg> {
let (n, s) = match modal.related_issues.len() {
1 => (1.to_string(), "issue"),

View File

@ -1,4 +1,6 @@
pub use {model::*, update::*, view::*};
pub use model::*;
pub use update::*;
pub use view::*;
mod model;
mod update;

View File

@ -1,8 +1,8 @@
use {
crate::{model::Model, Msg, OperationKind, ResourceKind},
jirs_data::WsMsg,
seed::prelude::*,
};
use jirs_data::WsMsg;
use seed::prelude::*;
use crate::model::Model;
use crate::{Msg, OperationKind, ResourceKind};
pub fn update(msg: &Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
let _modal = match &mut model.modals_mut().delete_issue_status_modal {

View File

@ -1,8 +1,9 @@
use {
crate::{components::styled_confirm_modal::StyledConfirmModal, model, shared::ToNode, Msg},
jirs_data::IssueStatusId,
seed::prelude::*,
};
use jirs_data::IssueStatusId;
use seed::prelude::*;
use crate::components::styled_confirm_modal::StyledConfirmModal;
use crate::shared::ToNode;
use crate::{model, Msg};
pub fn view(_model: &model::Model, issue_status_id: IssueStatusId) -> Node<Msg> {
StyledConfirmModal {

View File

@ -1,4 +1,6 @@
pub use {model::*, update::*, view::*};
pub use model::*;
pub use update::*;
pub use view::*;
mod model;
mod update;

View File

@ -1,17 +1,13 @@
use {
crate::{
components::{
styled_date_time_input::*, styled_input::*, styled_select::*, styled_select_child::*,
},
model::IssueModal,
shared::{IntoChild, ToNode},
FieldId, Msg,
},
derive_enum_iter::EnumIter,
derive_enum_primitive::EnumPrimitive,
jirs_data::{IssueFieldId, IssuePriority},
seed::prelude::*,
};
use derive_enum_iter::EnumIter;
use derive_enum_primitive::EnumPrimitive;
use jirs_data::{IssueFieldId, IssuePriority};
use seed::prelude::*;
use crate::components::styled_date_time_input::*;
use crate::components::styled_input::*;
use crate::components::styled_select::*;
use crate::model::IssueModal;
use crate::{FieldId, Msg};
#[derive(Copy, Clone, EnumPrimitive, EnumIter)]
pub enum Type {
@ -53,43 +49,6 @@ impl Type {
}
}
impl<'l> IntoChild<'l> for Type {
type Builder = StyledSelectChildBuilder<'l>;
fn into_child(self) -> Self::Builder {
let name = match self {
Type::Task => "Task",
Type::Bug => "Bug",
Type::Story => "Story",
Type::Epic => "Epic",
};
let value: u32 = self.into();
let type_icon = {
use crate::components::styled_icon::*;
StyledIcon {
icon: match self {
Type::Task => Icon::Task,
Type::Bug => Icon::Bug,
Type::Story => Icon::Story,
Type::Epic => Icon::Epic,
},
class_list: name,
..Default::default()
}
.into_node()
};
StyledSelectChildBuilder {
class_list: name,
text: Some(name),
icon: Some(type_icon),
value,
..Default::default()
}
}
}
#[derive(Clone, Debug, PartialOrd, PartialEq)]
pub struct Model {
pub priority: IssuePriority,

View File

@ -1,11 +1,10 @@
use {
crate::{
components::styled_select::StyledSelectChanged, model::IssueModal, ws::send_ws_msg,
FieldId, Msg, OperationKind, ResourceKind,
},
jirs_data::{IssueFieldId, UserId, WsMsg},
seed::prelude::*,
};
use jirs_data::{IssueFieldId, UserId, WsMsg};
use seed::prelude::*;
use crate::components::styled_select::StyledSelectChanged;
use crate::model::IssueModal;
use crate::ws::send_ws_msg;
use crate::{FieldId, Msg, OperationKind, ResourceKind};
pub fn update(msg: &Msg, model: &mut crate::model::Model, orders: &mut impl Orders<Msg>) {
let user_id = model.user_id().unwrap_or_default();

View File

@ -1,25 +1,23 @@
use {
crate::{
components::{
styled_button::StyledButton, styled_date_time_input::StyledDateTimeInput,
styled_field::StyledField, styled_form::StyledForm, styled_input::StyledInput,
styled_modal::StyledModal, styled_select::StyledSelect,
styled_textarea::StyledTextarea,
},
modals::{
epic_field,
issues_create::{Model as AddIssueModal, Type},
},
model::Model,
shared::{IntoChild, ToChild, ToNode},
FieldId, Msg,
},
jirs_data::{IssueFieldId, IssuePriority},
seed::{prelude::*, *},
};
use jirs_data::{IssueFieldId, IssuePriority, User};
use seed::prelude::*;
use seed::*;
use crate::components::styled_button::ButtonVariant;
use crate::components::styled_select::SelectVariant;
use crate::components::styled_avatar::StyledAvatar;
use crate::components::styled_button::{ButtonVariant, StyledButton};
use crate::components::styled_date_time_input::StyledDateTimeInput;
use crate::components::styled_field::StyledField;
use crate::components::styled_form::StyledForm;
use crate::components::styled_icon::{Icon, StyledIcon};
use crate::components::styled_input::StyledInput;
use crate::components::styled_modal::StyledModal;
use crate::components::styled_select::{SelectVariant, StyledSelect};
use crate::components::styled_select_child::StyledSelectChild;
use crate::components::styled_textarea::StyledTextarea;
use crate::modals::epic_field;
use crate::modals::issues_create::{Model as AddIssueModal, Type};
use crate::model::Model;
use crate::shared::ToNode;
use crate::{FieldId, Msg};
pub fn view(model: &Model, modal: &AddIssueModal) -> Node<Msg> {
let issue_type = modal
@ -40,26 +38,24 @@ pub fn view(model: &Model, modal: &AddIssueModal) -> Node<Msg> {
Type::Epic => {
let name_field = name_field(modal);
let starts = StyledField::build()
.input(
StyledDateTimeInput::build()
let starts = StyledField {
input: StyledDateTimeInput::build()
.state(&modal.epic_starts_at_state)
.build(FieldId::AddIssueModal(IssueFieldId::EpicStartsAt))
.into_node(),
)
.label("Starts at")
.build()
label: "Starts at",
..Default::default()
}
.into_node();
let end = StyledField::build()
.input(
StyledDateTimeInput::build()
let end = StyledField {
input: StyledDateTimeInput::build()
.state(&modal.epic_ends_at_state)
.build(FieldId::AddIssueModal(IssueFieldId::EpicEndsAt))
.into_node(),
)
.label("Ends at")
.build()
label: "Ends at",
..Default::default()
}
.into_node();
form.add_field(name_field).add_field(starts).add_field(end)
@ -129,19 +125,16 @@ fn issue_type_field(modal: &AddIssueModal) -> Node<Msg> {
text_filter: modal.type_state.text_filter.as_str(),
opened: modal.type_state.opened,
valid: true,
options: Some(Type::Task.into_iter().map(|t| t.into_child().name("type"))),
selected: vec![{
let v: Type = modal
options: Some(Type::Task.into_iter().map(type_select_option)),
selected: vec![type_select_option(
modal
.type_state
.values
.get(0)
.cloned()
.unwrap_or_default()
.into();
v
}
.into_child()
.name("type")],
.into(),
)],
..Default::default()
}
.into_node();
@ -154,6 +147,37 @@ fn issue_type_field(modal: &AddIssueModal) -> Node<Msg> {
.into_node()
}
#[inline(always)]
fn type_select_option<'l>(t: Type) -> StyledSelectChild<'l> {
let name = match t {
Type::Task => "Task",
Type::Bug => "Bug",
Type::Story => "Story",
Type::Epic => "Epic",
};
StyledSelectChild {
class_list: name,
text: Some(name),
icon: Some(
StyledIcon {
icon: match t {
Type::Task => Icon::Task,
Type::Bug => Icon::Bug,
Type::Story => Icon::Story,
Type::Epic => Icon::Epic,
},
class_list: name,
..Default::default()
}
.into_node(),
),
name: Some("type"),
value: t.into(),
..Default::default()
}
}
#[inline]
fn short_summary_field(modal: &AddIssueModal) -> Node<Msg> {
let short_summary = StyledInput {
@ -199,13 +223,13 @@ fn reporter_field(model: &Model, modal: &AddIssueModal) -> Node<Msg> {
variant: SelectVariant::Normal,
text_filter: modal.reporter_state.text_filter.as_str(),
opened: modal.reporter_state.opened,
options: Some(model.users.iter().map(|u| u.to_child().name("reporter"))),
options: Some(model.users.iter().map(reporter_select_option)),
selected: model
.users
.iter()
.filter_map(|user| {
if user.id == reporter_id {
Some(user.to_child().name("reporter"))
Some(reporter_select_option(user))
} else {
None
}
@ -224,6 +248,25 @@ fn reporter_field(model: &Model, modal: &AddIssueModal) -> Node<Msg> {
.into_node()
}
#[inline(always)]
fn reporter_select_option(user: &User) -> StyledSelectChild {
StyledSelectChild {
value: user.id as u32,
icon: Some(
StyledAvatar {
size: 20,
name: &user.name,
avatar_url: user.avatar_url.as_deref(),
..StyledAvatar::default()
}
.into_node(),
),
text: Some(user.name.as_str()),
name: Some("reporter"),
..Default::default()
}
}
fn assignees_field(model: &Model, modal: &AddIssueModal) -> Node<Msg> {
let assignees = StyledSelect {
id: FieldId::AddIssueModal(IssueFieldId::Assignees),
@ -231,13 +274,13 @@ fn assignees_field(model: &Model, modal: &AddIssueModal) -> Node<Msg> {
is_multi: true,
text_filter: modal.assignees_state.text_filter.as_str(),
opened: modal.assignees_state.opened,
options: Some(model.users.iter().map(|u| u.to_child().name("assignees"))),
options: Some(model.users.iter().map(assignee_select_option)),
selected: model
.users
.iter()
.filter_map(|user| {
if modal.user_ids.contains(&user.id) {
Some(user.to_child().name("assignees"))
Some(assignee_select_option(user))
} else {
None
}
@ -248,14 +291,34 @@ fn assignees_field(model: &Model, modal: &AddIssueModal) -> Node<Msg> {
..Default::default()
}
.into_node();
StyledField::build()
.input(assignees)
.label("Assignees")
.tip("")
.build()
StyledField {
input: assignees,
label: "Assignees",
tip: Some(""),
..Default::default()
}
.into_node()
}
#[inline(always)]
fn assignee_select_option(user: &User) -> StyledSelectChild {
StyledSelectChild {
value: user.id as u32,
icon: Some(
StyledAvatar {
size: 20,
name: &user.name,
avatar_url: user.avatar_url.as_deref(),
..StyledAvatar::default()
}
.into_node(),
),
text: Some(user.name.as_str()),
name: Some("assignees"),
..Default::default()
}
}
fn issue_priority_field(modal: &AddIssueModal) -> Node<Msg> {
let priorities = IssuePriority::default().into_iter();
let select_priority = StyledSelect {
@ -265,8 +328,8 @@ fn issue_priority_field(modal: &AddIssueModal) -> Node<Msg> {
text_filter: modal.priority_state.text_filter.as_str(),
opened: modal.priority_state.opened,
valid: true,
options: Some(priorities.map(|p| p.into_child().name("priority"))),
selected: vec![modal.priority.into_child().name("priority")],
options: Some(priorities.map(priority_select_option)),
selected: vec![priority_select_option(modal.priority)],
..Default::default()
}
.into_node();
@ -279,6 +342,24 @@ fn issue_priority_field(modal: &AddIssueModal) -> Node<Msg> {
.into_node()
}
fn priority_select_option<'l>(priority: IssuePriority) -> StyledSelectChild<'l> {
StyledSelectChild {
icon: Some(
StyledIcon {
icon: priority.clone().into(),
class_list: priority.to_str(),
..Default::default()
}
.into_node(),
),
text: Some(priority.to_str()),
class_list: priority.to_str(),
value: priority.into(),
name: Some("priority"),
..Default::default()
}
}
fn name_field(modal: &AddIssueModal) -> Node<Msg> {
let name = StyledInput {
value: modal.title_state.value.as_str(),

View File

@ -1,4 +1,6 @@
pub use {model::*, update::*, view::*};
pub use model::*;
pub use update::*;
pub use view::*;
mod model;
mod update;

View File

@ -1,7 +1,8 @@
use {
crate::{components::styled_confirm_modal::StyledConfirmModal, model, shared::ToNode, Msg},
seed::prelude::*,
};
use seed::prelude::*;
use crate::components::styled_confirm_modal::StyledConfirmModal;
use crate::shared::ToNode;
use crate::{model, Msg};
pub fn view(model: &model::Model) -> Node<Msg> {
let issue_id = match &model.modals().delete_issue_confirm {

View File

@ -1,4 +1,6 @@
pub use {model::*, update::*, view::*};
pub use model::*;
pub use update::*;
pub use view::*;
mod model;
mod update;

View File

@ -1,17 +1,13 @@
use {
crate::{
components::{
styled_date_time_input::StyledDateTimeInputState, styled_editor::Mode,
styled_editor::StyledEditorState, styled_input::StyledInputState,
styled_select::StyledSelectState,
},
modals::time_tracking::value_for_time_tracking,
model::{CommentForm, IssueModal},
EditIssueModalSection, FieldId, Msg,
},
jirs_data::{Issue, IssueFieldId, IssueId, TimeTracking, UpdateIssuePayload},
seed::prelude::*,
};
use jirs_data::{Issue, IssueFieldId, IssueId, TimeTracking, UpdateIssuePayload};
use seed::prelude::*;
use crate::components::styled_date_time_input::StyledDateTimeInputState;
use crate::components::styled_editor::{Mode, StyledEditorState};
use crate::components::styled_input::StyledInputState;
use crate::components::styled_select::StyledSelectState;
use crate::modals::time_tracking::value_for_time_tracking;
use crate::model::{CommentForm, IssueModal};
use crate::{EditIssueModalSection, FieldId, Msg};
#[derive(Clone, Debug, PartialOrd, PartialEq)]
pub struct Model {

View File

@ -1,13 +1,10 @@
use {
crate::{
components::styled_select::StyledSelectChanged,
model::{IssueModal, Model},
ws::send_ws_msg,
EditIssueModalSection, FieldChange, FieldId, Msg, OperationKind, ResourceKind,
},
jirs_data::*,
seed::prelude::*,
};
use jirs_data::*;
use seed::prelude::*;
use crate::components::styled_select::StyledSelectChanged;
use crate::model::{IssueModal, Model};
use crate::ws::send_ws_msg;
use crate::{EditIssueModalSection, FieldChange, FieldId, Msg, OperationKind, ResourceKind};
pub fn update(msg: &Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
let modal = match &mut model.modals.edit_issue {
@ -303,7 +300,6 @@ pub fn update(msg: &Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
}
//
// comments
//
Msg::StrInputChanged(
FieldId::EditIssueModal(EditIssueModalSection::Comment(CommentFieldId::Body)),
text,

View File

@ -1,26 +1,27 @@
use {
crate::{
components::{
styled_avatar::StyledAvatar, styled_button::StyledButton, styled_editor::StyledEditor,
styled_field::StyledField, styled_icon::Icon, styled_input::StyledInput,
styled_modal::*, styled_select::StyledSelect,
},
modals::{
epic_field, issues_edit::Model as EditIssueModal, time_tracking::time_tracking_field,
},
model::{ModalType, Model},
shared::{tracking_widget::tracking_link, IntoChild, ToChild, ToNode},
EditIssueModalSection, FieldChange, FieldId, Msg,
},
comments::*,
jirs_data::{CommentFieldId, IssueFieldId, IssuePriority, IssueType, TimeTracking},
seed::{prelude::*, *},
use comments::*;
use jirs_data::{
CommentFieldId, IssueFieldId, IssuePriority, IssueStatus, IssueType, TimeTracking,
UpdateIssuePayload, User,
};
use seed::prelude::*;
use seed::*;
use crate::components::styled_button::ButtonVariant;
use crate::components::styled_icon::StyledIcon;
use crate::components::styled_select::SelectVariant;
use crate::components::styled_select_child::StyledSelectChildBuilder;
use crate::components::styled_avatar::StyledAvatar;
use crate::components::styled_button::{ButtonVariant, StyledButton};
use crate::components::styled_editor::StyledEditor;
use crate::components::styled_field::StyledField;
use crate::components::styled_icon::{Icon, StyledIcon};
use crate::components::styled_input::StyledInput;
use crate::components::styled_modal::*;
use crate::components::styled_select::{SelectVariant, StyledSelect, StyledSelectState};
use crate::components::styled_select_child::StyledSelectChild;
use crate::modals::epic_field;
use crate::modals::issues_edit::Model as EditIssueModal;
use crate::modals::time_tracking::time_tracking_field;
use crate::model::{ModalType, Model};
use crate::shared::tracking_widget::tracking_link;
use crate::shared::ToNode;
use crate::{EditIssueModalSection, FieldChange, FieldId, Msg};
mod comments;
@ -149,27 +150,9 @@ fn modal_header(_model: &Model, modal: &EditIssueModal) -> Node<Msg> {
options: Some(
IssueType::default()
.into_iter()
.map(|t| t.into_child().name("type")),
.map(|t| type_select_option(t, &text)),
),
selected: vec![{
let name = payload.issue_type.to_label();
let type_icon = StyledIcon {
icon: payload.issue_type.clone().into(),
class_list: name,
..Default::default()
}
.into_node();
StyledSelectChildBuilder {
class_list: name,
text: Some(&text),
icon: Some(type_icon),
value: payload.issue_type.into(),
name: Some("type"),
..Default::default()
}
}],
selected: vec![type_select_option(payload.issue_type, &text)],
..Default::default()
}
.into_node()
@ -187,6 +170,26 @@ fn modal_header(_model: &Model, modal: &EditIssueModal) -> Node<Msg> {
]
}
#[inline(always)]
fn type_select_option<'l>(t: IssueType, text: &'l str) -> StyledSelectChild<'l> {
let name = t.to_label();
StyledSelectChild {
class_list: name,
text: Some(text),
icon: Some(
StyledIcon {
icon: t.clone().into(),
class_list: name,
..Default::default()
}
.into_node(),
),
value: t.into(),
name: Some("type"),
..Default::default()
}
}
fn left_modal_column(model: &Model, modal: &EditIssueModal) -> Node<Msg> {
let EditIssueModal {
payload,
@ -220,7 +223,11 @@ fn left_modal_column(model: &Model, modal: &EditIssueModal) -> Node<Msg> {
}
.into_node()
};
let description_field = StyledField::build().input(description).build().into_node();
let description_field = StyledField {
input: description,
..Default::default()
}
.into_node();
let user_avatar = StyledAvatar {
avatar_url: model.user.as_ref().and_then(|u| u.avatar_url.as_deref()),
@ -283,110 +290,13 @@ fn right_modal_column(model: &Model, modal: &EditIssueModal) -> Node<Msg> {
..
} = modal;
let status = StyledSelect {
id: FieldId::EditIssueModal(EditIssueModalSection::Issue(IssueFieldId::IssueStatusId)),
name: "status",
opened: status_state.opened,
variant: SelectVariant::Normal,
text_filter: status_state.text_filter.as_str(),
options: Some(
model
.issue_statuses
.iter()
.map(|opt| opt.to_child().name("status")),
),
selected: model
.issue_statuses
.iter()
.filter(|is| is.id == payload.issue_status_id)
.map(|is| is.to_child().name("status"))
.collect(),
let status_field = status_select(model, payload, status_state);
valid: true,
..Default::default()
}
.into_node();
let status_field = StyledField::build()
.input(status)
.label("Status")
.build()
.into_node();
let assignees_field = assignees_select(model, payload, assignees_state);
let assignees = StyledSelect {
id: FieldId::EditIssueModal(EditIssueModalSection::Issue(IssueFieldId::Assignees)),
name: "assignees",
variant: SelectVariant::Empty,
is_multi: true,
opened: assignees_state.opened,
text_filter: assignees_state.text_filter.as_str(),
options: Some(
model
.users
.iter()
.map(|user| user.to_child().name("assignees")),
),
selected: model
.users
.iter()
.filter(|user| payload.user_ids.contains(&user.id))
.map(|user| user.to_child().name("assignees"))
.collect(),
..Default::default()
}
.into_node();
let assignees_field = StyledField::build()
.input(assignees)
.label("Assignees")
.build()
.into_node();
let reporter_field = reporters_select(model, payload, reporter_state);
let reporter = StyledSelect {
id: FieldId::EditIssueModal(EditIssueModalSection::Issue(IssueFieldId::Reporter)),
name: "reporter",
opened: reporter_state.opened,
variant: SelectVariant::Empty,
text_filter: reporter_state.text_filter.as_str(),
options: Some(
model
.users
.iter()
.map(|user| user.to_child().name("reporter")),
),
selected: model
.users
.iter()
.filter(|user| payload.reporter_id == user.id)
.map(|user| user.to_child().name("reporter"))
.collect(),
..Default::default()
}
.into_node();
let reporter_field = StyledField::build()
.input(reporter)
.label("Reporter")
.build()
.into_node();
let priority = StyledSelect {
id: FieldId::EditIssueModal(EditIssueModalSection::Issue(IssueFieldId::Priority)),
name: "priority",
variant: SelectVariant::Empty,
opened: priority_state.opened,
text_filter: priority_state.text_filter.as_str(),
options: Some(
IssuePriority::default()
.into_iter()
.map(|p| p.into_child().name("priority")),
),
selected: vec![payload.priority.into_child().name("priority")],
..Default::default()
}
.into_node();
let priority_field = StyledField::build()
.input(priority)
.label("Priority")
.build()
.into_node();
let priority_field = priorities_select(payload, priority_state);
let time_tracking_type = model
.project
@ -404,11 +314,12 @@ fn right_modal_column(model: &Model, modal: &EditIssueModal) -> Node<Msg> {
);
let tracking = tracking_link(model, modal);
let tracking_field = StyledField::build()
.label("TIME TRACKING")
.tip("")
.input(tracking)
.build()
let tracking_field = StyledField {
label: "TIME TRACKING",
tip: Some(""),
input: tracking,
..Default::default()
}
.into_node();
(estimate_field, tracking_field)
} else {
@ -433,3 +344,192 @@ fn right_modal_column(model: &Model, modal: &EditIssueModal) -> Node<Msg> {
epic_field,
]
}
#[inline(always)]
fn priorities_select(
payload: &UpdateIssuePayload,
priority_state: &StyledSelectState,
) -> Node<Msg> {
let priority = StyledSelect {
id: FieldId::EditIssueModal(EditIssueModalSection::Issue(IssueFieldId::Priority)),
name: "priority",
variant: SelectVariant::Empty,
opened: priority_state.opened,
text_filter: priority_state.text_filter.as_str(),
options: Some(
IssuePriority::default()
.into_iter()
.map(priority_select_option),
),
selected: vec![priority_select_option(payload.priority)],
..Default::default()
}
.into_node();
StyledField {
label: "Priority",
input: priority,
..Default::default()
}
.into_node()
}
#[inline(always)]
fn priority_select_option<'l>(ip: IssuePriority) -> StyledSelectChild<'l> {
StyledSelectChild {
icon: Some(
StyledIcon {
icon: ip.clone().into(),
class_list: ip.to_str(),
..Default::default()
}
.into_node(),
),
text: Some(ip.to_str()),
class_list: ip.to_str(),
value: ip.into(),
name: Some("priority"),
..Default::default()
}
}
#[inline(always)]
fn status_select(
model: &Model,
payload: &UpdateIssuePayload,
status_state: &StyledSelectState,
) -> Node<Msg> {
let status = StyledSelect {
id: FieldId::EditIssueModal(EditIssueModalSection::Issue(IssueFieldId::IssueStatusId)),
name: "status",
opened: status_state.opened,
variant: SelectVariant::Normal,
text_filter: status_state.text_filter.as_str(),
options: Some(model.issue_statuses.iter().map(issue_status_select_option)),
selected: model
.issue_statuses
.iter()
.filter(|is| is.id == payload.issue_status_id)
.map(issue_status_select_option)
.collect(),
valid: true,
..Default::default()
}
.into_node();
StyledField {
label: "Status",
input: status,
..Default::default()
}
.into_node()
}
#[inline(always)]
fn issue_status_select_option<'l>(is: &'l IssueStatus) -> StyledSelectChild<'l> {
StyledSelectChild {
value: is.id as u32,
class_list: is.name.as_str(),
text: Some(is.name.as_str()),
name: Some("status"),
..Default::default()
}
}
#[inline(always)]
fn reporters_select(
model: &Model,
payload: &UpdateIssuePayload,
reporter_state: &StyledSelectState,
) -> Node<Msg> {
let reporter = StyledSelect {
id: FieldId::EditIssueModal(EditIssueModalSection::Issue(IssueFieldId::Reporter)),
name: "reporter",
opened: reporter_state.opened,
variant: SelectVariant::Empty,
text_filter: reporter_state.text_filter.as_str(),
options: Some(model.users.iter().map(reporter_select_option)),
selected: model
.users
.iter()
.filter(|user| payload.reporter_id == user.id)
.map(reporter_select_option)
.collect(),
..Default::default()
}
.into_node();
StyledField {
label: "Reporter",
input: reporter,
..Default::default()
}
.into_node()
}
#[inline(always)]
fn reporter_select_option<'l>(user: &'l User) -> StyledSelectChild<'l> {
StyledSelectChild {
value: user.id as u32,
icon: Some(
StyledAvatar {
size: 20,
name: &user.name,
avatar_url: user.avatar_url.as_deref(),
..StyledAvatar::default()
}
.into_node(),
),
text: Some(user.name.as_str()),
name: Some("reporter"),
..Default::default()
}
}
#[inline(always)]
fn assignees_select(
model: &Model,
payload: &UpdateIssuePayload,
assignees_state: &StyledSelectState,
) -> Node<Msg> {
let assignees = StyledSelect {
id: FieldId::EditIssueModal(EditIssueModalSection::Issue(IssueFieldId::Assignees)),
name: "assignees",
variant: SelectVariant::Empty,
is_multi: true,
opened: assignees_state.opened,
text_filter: assignees_state.text_filter.as_str(),
options: Some(model.users.iter().map(assignee_select_option)),
selected: model
.users
.iter()
.filter(|user| payload.user_ids.contains(&user.id))
.map(assignee_select_option)
.collect(),
..Default::default()
}
.into_node();
StyledField {
input: assignees,
label: "Assignees",
..Default::default()
}
.into_node()
}
#[inline(always)]
fn assignee_select_option<'l>(user: &'l User) -> StyledSelectChild<'l> {
StyledSelectChild {
value: user.id as u32,
icon: Some(
StyledAvatar {
size: 20,
name: &user.name,
avatar_url: user.avatar_url.as_deref(),
..StyledAvatar::default()
}
.into_node(),
),
text: Some(user.name.as_str()),
name: Some("assignees"),
..Default::default()
}
}

View File

@ -1,19 +1,14 @@
use {
crate::{
components::{
styled_avatar::StyledAvatar, styled_button::StyledButton,
styled_textarea::StyledTextarea,
},
modals::issues_edit::Model as EditIssueModal,
model::{CommentForm, ModalType, Model},
shared::ToNode,
EditIssueModalSection, FieldChange, FieldId, Msg,
},
jirs_data::{Comment, CommentFieldId},
seed::{prelude::*, *},
};
use jirs_data::{Comment, CommentFieldId};
use seed::prelude::*;
use seed::*;
use crate::components::styled_button::ButtonVariant;
use crate::components::styled_avatar::StyledAvatar;
use crate::components::styled_button::{ButtonVariant, StyledButton};
use crate::components::styled_textarea::StyledTextarea;
use crate::modals::issues_edit::Model as EditIssueModal;
use crate::model::{CommentForm, ModalType, Model};
use crate::shared::ToNode;
use crate::{EditIssueModalSection, FieldChange, FieldId, Msg};
pub fn build_comment_form(form: &CommentForm) -> Vec<Node<Msg>> {
let submit_comment_form = mouse_ev(Ev::Click, move |ev| {

View File

@ -1,4 +1,6 @@
pub use {epic_field::*, update::*, view::*};
pub use epic_field::*;
pub use update::*;
pub use view::*;
pub mod comments_delete;
#[cfg(debug_assertions)]

View File

@ -1,4 +1,6 @@
pub use {model::*, update::*, view::*};
pub use model::*;
pub use update::*;
pub use view::*;
mod model;
mod update;

View File

@ -1,22 +1,17 @@
use {
crate::{
components::{
styled_button::StyledButton,
styled_field::StyledField,
styled_input::{StyledInput, StyledInputState},
styled_modal::StyledModal,
styled_select::{StyledSelect, StyledSelectState},
},
model::Model,
shared::{
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 seed::prelude::*;
use seed::*;
use crate::components::styled_button::StyledButton;
use crate::components::styled_field::StyledField;
use crate::components::styled_input::{StyledInput, StyledInputState};
use crate::components::styled_modal::StyledModal;
use crate::components::styled_select::{StyledSelect, StyledSelectState};
use crate::components::styled_select_child::StyledSelectChild;
use crate::model::Model;
use crate::shared::tracking_widget::{fibonacci_value_name, fibonacci_values, tracking_widget};
use crate::shared::ToNode;
use crate::{EditIssueModalSection, FieldId, Msg};
pub fn value_for_time_tracking(v: &Option<i32>, time_tracking_type: &TimeTracking) -> String {
match (time_tracking_type, v.as_ref()) {
@ -85,7 +80,7 @@ pub fn view(model: &Model, modal: &super::Model) -> Node<Msg> {
.into_node()
}
#[inline]
#[inline(always)]
pub fn time_tracking_field(
time_tracking_type: TimeTracking,
field_id: FieldId,
@ -101,12 +96,18 @@ pub fn time_tracking_field(
selected: select_state
.values
.iter()
.map(|n| (*n).to_child())
.copied()
.map(fibonacci_value_select_option)
.collect(),
text_filter: select_state.text_filter.as_str(),
opened: select_state.opened,
options: Some(fibonacci_values.iter().map(|v| v.to_child())),
options: Some(
fibonacci_values
.iter()
.copied()
.map(fibonacci_value_select_option),
),
..Default::default()
}
.into_node(),
@ -125,3 +126,14 @@ pub fn time_tracking_field(
}
.into_node()
}
fn fibonacci_value_select_option<'l>(value: u32) -> StyledSelectChild<'l> {
let name = fibonacci_value_name(value);
StyledSelectChild {
class_list: name,
text: Some(name),
value,
..Default::default()
}
}

View File

@ -1,14 +1,11 @@
use jirs_data::{CommentId, IssueStatusId};
use {
crate::{
model::{ModalType, Model, Page},
shared::go_to_board,
ws::send_ws_msg,
FieldChange, FieldId, Msg, OperationKind, ResourceKind,
},
jirs_data::{EpicId, IssueId, TimeTracking, WsMsg},
seed::{prelude::*, *},
};
use jirs_data::{CommentId, EpicId, IssueId, IssueStatusId, TimeTracking, WsMsg};
use seed::prelude::*;
use seed::*;
use crate::model::{ModalType, Model, Page};
use crate::shared::go_to_board;
use crate::ws::send_ws_msg;
use crate::{FieldChange, FieldId, Msg, OperationKind, ResourceKind};
pub fn update(msg: &Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
match msg {

View File

@ -1,7 +1,8 @@
use {
crate::{model::*, Msg},
seed::{prelude::*, *},
};
use seed::prelude::*;
use seed::*;
use crate::model::*;
use crate::Msg;
pub fn view(model: &Model) -> Node<Msg> {
let nodes = model

View File

@ -1,20 +1,21 @@
use {
crate::{
components::styled_select::StyledSelectState,
pages::{
invite_page::InvitePage, profile_page::model::ProfilePage,
project_page::model::ProjectPage, project_settings_page::ProjectSettingsPage,
reports_page::model::ReportsPage, sign_in_page::model::SignInPage,
sign_up_page::model::SignUpPage, users_page::model::UsersPage,
},
Msg,
},
jirs_data::*,
seed::{app::Orders, browser::web_socket::WebSocket},
serde::{Deserialize, Serialize},
std::collections::hash_map::HashMap,
uuid::Uuid,
};
use std::collections::hash_map::HashMap;
use jirs_data::*;
use seed::app::Orders;
use seed::browser::web_socket::WebSocket;
use serde::{Deserialize, Serialize};
use uuid::Uuid;
use crate::components::styled_select::StyledSelectState;
use crate::pages::invite_page::InvitePage;
use crate::pages::profile_page::model::ProfilePage;
use crate::pages::project_page::model::ProjectPage;
use crate::pages::project_settings_page::ProjectSettingsPage;
use crate::pages::reports_page::model::ReportsPage;
use crate::pages::sign_in_page::model::SignInPage;
use crate::pages::sign_up_page::model::SignUpPage;
use crate::pages::users_page::model::UsersPage;
use crate::Msg;
pub trait IssueModal {
fn epic_id_value(&self) -> Option<u32>;

View File

@ -1,4 +1,6 @@
pub use {model::*, update::*, view::*};
pub use model::*;
pub use update::*;
pub use view::*;
mod model;
mod update;

View File

@ -1,15 +1,15 @@
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,
use std::str::FromStr;
use jirs_data::fields::*;
use jirs_data::WsMsg;
use seed::prelude::*;
use crate::model::{Model, Page, PageContent};
use crate::pages::invite_page::InvitePage;
use crate::shared::write_auth_token;
use crate::ws::send_ws_msg;
use crate::{
authorize_or_redirect, FieldId, InvitationPageChange, Msg, PageChanged, WebSocketChanged,
};
pub fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {

View File

@ -1,21 +1,16 @@
use {
crate::{
components::{
styled_button::StyledButton, styled_field::StyledField, styled_form::StyledForm,
styled_input::StyledInput,
},
match_page,
model::{Model, PageContent},
pages::invite_page::InvitePage,
shared::{outer_layout, ToNode},
validations::is_token,
FieldId, InvitationPageChange, Msg, PageChanged,
},
jirs_data::fields::*,
seed::{prelude::*, *},
};
use jirs_data::fields::*;
use seed::prelude::*;
use seed::*;
use crate::components::styled_button::ButtonVariant;
use crate::components::styled_button::{ButtonVariant, StyledButton};
use crate::components::styled_field::StyledField;
use crate::components::styled_form::StyledForm;
use crate::components::styled_input::StyledInput;
use crate::model::{Model, PageContent};
use crate::pages::invite_page::InvitePage;
use crate::shared::{outer_layout, ToNode};
use crate::validations::is_token;
use crate::{match_page, FieldId, InvitationPageChange, Msg, PageChanged};
pub fn view(model: &Model) -> Node<Msg> {
let page = match_page!(model, Invite; Empty);

Some files were not shown because too many files have changed in this diff Show More