Start notifications. Disable work in progress features

This commit is contained in:
Adrian Wozniak 2020-05-20 15:41:54 +02:00
parent 778f56cf8d
commit 92e129115a
9 changed files with 105 additions and 33 deletions

View File

@ -62,19 +62,15 @@ aside#navbar-left .item > .styledIcon > .styledAvatar {
height: 27px;
}
aside#navbar-left > .item > .styledIcon.search {
aside#navbar-left > .item > i.styledIcon.search {
font-size: 22px;
color: #DEEBFE;
color: var(--asideIcon);
}
aside#navbar-left > .item > .styledIcon.plus {
aside#navbar-left > .item > i.styledIcon,
aside#navbar-left > .bottom > .item > i.styledIcon {
font-size: 27px;
color: #DEEBFE;
}
aside#navbar-left .item > .styledIcon.help {
font-size: 27px;
color: #DEEBFE;
color: var(--asideIcon);
}
aside#navbar-left .item > .itemText {
@ -97,7 +93,8 @@ aside#navbar-left > .bottom {
width: 100%;
}
aside#navbar-left > .bottom > .aboutTooltip {
aside#navbar-left > .bottom > .aboutTooltip > .item > i.styledIcon {
color: var(--asideIcon);
}
aside#navbar-left:hover .item > .itemText {

View File

@ -73,6 +73,12 @@ nav#sidebar .linkItem > a {
nav#sidebar .linkItem.notAllowed, nav#sidebar .linkItem.notAllowed > a {
cursor: not-allowed;
color: var(--textDark);
}
nav#sidebar .linkItem.notAllowed, nav#sidebar .linkItem.notAllowed > a > .styledIcon {
cursor: not-allowed;
color: var(--textDark);
}
nav#sidebar .linkItem:hover {

View File

@ -168,3 +168,11 @@ i.styledIcon.arrowRight:before {
font-family: "jira";
content: "\e91f";
}
i.styledIcon.user:before {
content: "\ec8e";
}
i.styledIcon.message:before {
content: "\efac";
}

View File

@ -1,12 +1,19 @@
.styledImageInput {
}
.styledImageInput > .label {
width: 120px;
height: 120px;
margin: 0 auto;
display: block;
}
.styledImageInput > .label > .mask {
display: block;
width: 120px;
height: 120px;
margin: 0 auto;
border-radius: 60px;
cursor: pointer;
}
.styledImageInput > .input {

View File

@ -18,6 +18,7 @@
--borderLightest: rgb(223, 225, 230);
--borderLight: rgb(193, 199, 208);
--borderInputFocus: rgb(76, 154, 255);
--asideIcon: rgb(222, 235, 254);
}
:root {

View File

@ -1,5 +1,6 @@
use std::collections::hash_map::HashMap;
use seed::browser::web_socket::WebSocket;
use serde::{Deserialize, Serialize};
use uuid::Uuid;
@ -13,7 +14,6 @@ use crate::shared::styled_image_input::StyledImageInputState;
use crate::shared::styled_input::StyledInputState;
use crate::shared::styled_select::StyledSelectState;
use crate::{EditIssueModalSection, FieldId, ProjectFieldId /*HOST_URL*/};
use seed::browser::web_socket::WebSocket;
#[derive(Clone, Debug, PartialOrd, PartialEq)]
pub enum ModalType {
@ -460,6 +460,7 @@ pub struct Model {
pub users: Vec<User>,
pub comments: Vec<Comment>,
pub issue_statuses: Vec<IssueStatus>,
pub messages: Vec<Message>,
}
impl Model {
@ -483,6 +484,17 @@ impl Model {
comments: vec![],
about_tooltip_visible: false,
issue_statuses: vec![],
messages: vec![Message {
id: 0,
receiver_id: 1,
sender_id: 2,
summary: "You have been invited".to_string(),
description: "You have been invited to project A".to_string(),
message_type: "project-invitation".to_string(),
hyper_link: "/project/1".to_string(),
created_at: chrono::NaiveDateTime::from_timestamp(4567890, 123),
updated_at: chrono::NaiveDateTime::from_timestamp(1234567, 098),
}],
}
}
}

View File

@ -3,10 +3,26 @@ use seed::{prelude::*, *};
use crate::model::Model;
use crate::shared::styled_avatar::StyledAvatar;
use crate::shared::styled_button::StyledButton;
use crate::shared::styled_icon::Icon;
use crate::shared::styled_icon::{Icon, StyledIcon};
use crate::shared::{styled_tooltip, ToNode};
use crate::Msg;
trait IntoNavItemIcon {
fn into_nav_item_icon(self) -> Node<Msg>;
}
impl IntoNavItemIcon for Node<Msg> {
fn into_nav_item_icon(self) -> Node<Msg> {
self
}
}
impl IntoNavItemIcon for Icon {
fn into_nav_item_icon(self) -> Node<Msg> {
StyledIcon::build(self).size(21).build().into_node()
}
}
pub fn render(model: &Model) -> Vec<Node<Msg>> {
let logo_svg = Node::from_html(include_str!("../../static/logo.svg"));
@ -20,7 +36,13 @@ pub fn render(model: &Model) -> Vec<Node<Msg>> {
.build()
.into_node()
],
_ => i![attrs![At::Class => format!("styledIcon {}", Icon::Plus)]],
_ => StyledIcon::build(Icon::User).size(21).build().into_node(),
};
let messages = if model.messages.is_empty() {
empty![]
} else {
navbar_left_item("Messages", Icon::Message, None)
};
vec![
@ -31,30 +53,28 @@ pub fn render(model: &Model) -> Vec<Node<Msg>> {
attrs![At::Class => "logoLink", At::Href => "/"],
div![attrs![At::Class => "styledLogo"], logo_svg]
],
navbar_left_item(model, "Search issues", Icon::Search),
a![
attrs![At::Class => "item"; At::Href=> "/add-issue"; ],
i![attrs![At::Class => format!("styledIcon {}", Icon::Plus)]],
span![attrs![At::Class => "itemText"], "Create Issue"]
],
navbar_left_item("Search issues", Icon::Search, None),
navbar_left_item("Create Issue", Icon::Plus, Some("/add-issue")),
div![
class!["bottom"],
div![
class!["item"],
attrs![At::Href=> "/profile"],
user_icon,
span![class!["itemText"], "Profile"]
],
about_tooltip(model, navbar_left_item(model, "About", Icon::Help)),
navbar_left_item("Profile", user_icon, Some("/profile")),
messages,
about_tooltip(model, navbar_left_item("About", Icon::Help, None)),
],
],
]
}
fn navbar_left_item(_model: &Model, text: &str, logo: Icon) -> Node<Msg> {
div![
fn navbar_left_item<I>(text: &str, icon: I, href: Option<&str>) -> Node<Msg>
where
I: IntoNavItemIcon,
{
let styled_icon = icon.into_nav_item_icon();
let href = href.unwrap_or_else(|| "#");
a![
class!["item"],
i![attrs![At::Class => format!("styledIcon {}", logo)]],
attrs![At::Href => href],
styled_icon,
span![class!["itemText"], text]
]
}

View File

@ -41,6 +41,8 @@ pub enum Icon {
ArrowLeft,
ArrowRight,
Cop,
Message,
User,
}
impl Icon {
@ -92,6 +94,8 @@ impl std::fmt::Display for Icon {
Icon::ArrowLeft => "arrowLeft",
Icon::ArrowRight => "arrowRight",
Icon::Cop => "cop",
Icon::Message => "message",
Icon::User => "user",
};
f.write_str(code)
}

View File

@ -26,6 +26,7 @@ pub type TokenId = i32;
pub type IssueStatusId = i32;
pub type InvitationId = i32;
pub type Position = i32;
pub type MessageId = i32;
pub type EmailString = String;
pub type UsernameString = String;
pub type TitleString = String;
@ -506,8 +507,8 @@ pub struct UpdateIssuePayload {
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct IssueAssignee {
pub id: i32,
pub issue_id: i32,
pub user_id: i32,
pub issue_id: IssueId,
pub user_id: UserId,
pub created_at: NaiveDateTime,
pub updated_at: NaiveDateTime,
}
@ -532,6 +533,19 @@ impl From<Issue> for UpdateIssuePayload {
}
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct Message {
pub id: MessageId,
pub receiver_id: UserId,
pub sender_id: UserId,
pub summary: String,
pub description: String,
pub message_type: String,
pub hyper_link: String,
pub created_at: NaiveDateTime,
pub updated_at: NaiveDateTime,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct CreateCommentPayload {
pub user_id: Option<UserId>,
@ -541,7 +555,7 @@ pub struct CreateCommentPayload {
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct UpdateCommentPayload {
pub id: i32,
pub id: CommentId,
pub body: String,
}
@ -719,4 +733,7 @@ pub enum WsMsg {
AvatarUrlChanged(UserId, String),
ProfileUpdate(EmailString, UsernameString),
ProfileUpdated,
// messages
Message(Message),
}