Start notifications. Disable work in progress features
This commit is contained in:
parent
778f56cf8d
commit
92e129115a
@ -62,19 +62,15 @@ aside#navbar-left .item > .styledIcon > .styledAvatar {
|
|||||||
height: 27px;
|
height: 27px;
|
||||||
}
|
}
|
||||||
|
|
||||||
aside#navbar-left > .item > .styledIcon.search {
|
aside#navbar-left > .item > i.styledIcon.search {
|
||||||
font-size: 22px;
|
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;
|
font-size: 27px;
|
||||||
color: #DEEBFE;
|
color: var(--asideIcon);
|
||||||
}
|
|
||||||
|
|
||||||
aside#navbar-left .item > .styledIcon.help {
|
|
||||||
font-size: 27px;
|
|
||||||
color: #DEEBFE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
aside#navbar-left .item > .itemText {
|
aside#navbar-left .item > .itemText {
|
||||||
@ -97,7 +93,8 @@ aside#navbar-left > .bottom {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
aside#navbar-left > .bottom > .aboutTooltip {
|
aside#navbar-left > .bottom > .aboutTooltip > .item > i.styledIcon {
|
||||||
|
color: var(--asideIcon);
|
||||||
}
|
}
|
||||||
|
|
||||||
aside#navbar-left:hover .item > .itemText {
|
aside#navbar-left:hover .item > .itemText {
|
||||||
|
@ -73,6 +73,12 @@ nav#sidebar .linkItem > a {
|
|||||||
|
|
||||||
nav#sidebar .linkItem.notAllowed, nav#sidebar .linkItem.notAllowed > a {
|
nav#sidebar .linkItem.notAllowed, nav#sidebar .linkItem.notAllowed > a {
|
||||||
cursor: not-allowed;
|
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 {
|
nav#sidebar .linkItem:hover {
|
||||||
|
@ -168,3 +168,11 @@ i.styledIcon.arrowRight:before {
|
|||||||
font-family: "jira";
|
font-family: "jira";
|
||||||
content: "\e91f";
|
content: "\e91f";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
i.styledIcon.user:before {
|
||||||
|
content: "\ec8e";
|
||||||
|
}
|
||||||
|
|
||||||
|
i.styledIcon.message:before {
|
||||||
|
content: "\efac";
|
||||||
|
}
|
||||||
|
@ -1,12 +1,19 @@
|
|||||||
.styledImageInput {
|
.styledImageInput {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.styledImageInput > .label {
|
||||||
|
width: 120px;
|
||||||
|
height: 120px;
|
||||||
|
margin: 0 auto;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
.styledImageInput > .label > .mask {
|
.styledImageInput > .label > .mask {
|
||||||
display: block;
|
display: block;
|
||||||
width: 120px;
|
width: 120px;
|
||||||
height: 120px;
|
height: 120px;
|
||||||
margin: 0 auto;
|
|
||||||
border-radius: 60px;
|
border-radius: 60px;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.styledImageInput > .input {
|
.styledImageInput > .input {
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
--borderLightest: rgb(223, 225, 230);
|
--borderLightest: rgb(223, 225, 230);
|
||||||
--borderLight: rgb(193, 199, 208);
|
--borderLight: rgb(193, 199, 208);
|
||||||
--borderInputFocus: rgb(76, 154, 255);
|
--borderInputFocus: rgb(76, 154, 255);
|
||||||
|
--asideIcon: rgb(222, 235, 254);
|
||||||
}
|
}
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use std::collections::hash_map::HashMap;
|
use std::collections::hash_map::HashMap;
|
||||||
|
|
||||||
|
use seed::browser::web_socket::WebSocket;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
@ -13,7 +14,6 @@ use crate::shared::styled_image_input::StyledImageInputState;
|
|||||||
use crate::shared::styled_input::StyledInputState;
|
use crate::shared::styled_input::StyledInputState;
|
||||||
use crate::shared::styled_select::StyledSelectState;
|
use crate::shared::styled_select::StyledSelectState;
|
||||||
use crate::{EditIssueModalSection, FieldId, ProjectFieldId /*HOST_URL*/};
|
use crate::{EditIssueModalSection, FieldId, ProjectFieldId /*HOST_URL*/};
|
||||||
use seed::browser::web_socket::WebSocket;
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialOrd, PartialEq)]
|
#[derive(Clone, Debug, PartialOrd, PartialEq)]
|
||||||
pub enum ModalType {
|
pub enum ModalType {
|
||||||
@ -460,6 +460,7 @@ pub struct Model {
|
|||||||
pub users: Vec<User>,
|
pub users: Vec<User>,
|
||||||
pub comments: Vec<Comment>,
|
pub comments: Vec<Comment>,
|
||||||
pub issue_statuses: Vec<IssueStatus>,
|
pub issue_statuses: Vec<IssueStatus>,
|
||||||
|
pub messages: Vec<Message>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Model {
|
impl Model {
|
||||||
@ -483,6 +484,17 @@ impl Model {
|
|||||||
comments: vec![],
|
comments: vec![],
|
||||||
about_tooltip_visible: false,
|
about_tooltip_visible: false,
|
||||||
issue_statuses: vec![],
|
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),
|
||||||
|
}],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,10 +3,26 @@ use seed::{prelude::*, *};
|
|||||||
use crate::model::Model;
|
use crate::model::Model;
|
||||||
use crate::shared::styled_avatar::StyledAvatar;
|
use crate::shared::styled_avatar::StyledAvatar;
|
||||||
use crate::shared::styled_button::StyledButton;
|
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::shared::{styled_tooltip, ToNode};
|
||||||
use crate::Msg;
|
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>> {
|
pub fn render(model: &Model) -> Vec<Node<Msg>> {
|
||||||
let logo_svg = Node::from_html(include_str!("../../static/logo.svg"));
|
let logo_svg = Node::from_html(include_str!("../../static/logo.svg"));
|
||||||
|
|
||||||
@ -20,7 +36,13 @@ pub fn render(model: &Model) -> Vec<Node<Msg>> {
|
|||||||
.build()
|
.build()
|
||||||
.into_node()
|
.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![
|
vec![
|
||||||
@ -31,30 +53,28 @@ pub fn render(model: &Model) -> Vec<Node<Msg>> {
|
|||||||
attrs![At::Class => "logoLink", At::Href => "/"],
|
attrs![At::Class => "logoLink", At::Href => "/"],
|
||||||
div![attrs![At::Class => "styledLogo"], logo_svg]
|
div![attrs![At::Class => "styledLogo"], logo_svg]
|
||||||
],
|
],
|
||||||
navbar_left_item(model, "Search issues", Icon::Search),
|
navbar_left_item("Search issues", Icon::Search, None),
|
||||||
a![
|
navbar_left_item("Create Issue", Icon::Plus, Some("/add-issue")),
|
||||||
attrs![At::Class => "item"; At::Href=> "/add-issue"; ],
|
|
||||||
i![attrs![At::Class => format!("styledIcon {}", Icon::Plus)]],
|
|
||||||
span![attrs![At::Class => "itemText"], "Create Issue"]
|
|
||||||
],
|
|
||||||
div![
|
div![
|
||||||
class!["bottom"],
|
class!["bottom"],
|
||||||
div![
|
navbar_left_item("Profile", user_icon, Some("/profile")),
|
||||||
class!["item"],
|
messages,
|
||||||
attrs![At::Href=> "/profile"],
|
about_tooltip(model, navbar_left_item("About", Icon::Help, None)),
|
||||||
user_icon,
|
|
||||||
span![class!["itemText"], "Profile"]
|
|
||||||
],
|
|
||||||
about_tooltip(model, navbar_left_item(model, "About", Icon::Help)),
|
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn navbar_left_item(_model: &Model, text: &str, logo: Icon) -> Node<Msg> {
|
fn navbar_left_item<I>(text: &str, icon: I, href: Option<&str>) -> Node<Msg>
|
||||||
div![
|
where
|
||||||
|
I: IntoNavItemIcon,
|
||||||
|
{
|
||||||
|
let styled_icon = icon.into_nav_item_icon();
|
||||||
|
let href = href.unwrap_or_else(|| "#");
|
||||||
|
a![
|
||||||
class!["item"],
|
class!["item"],
|
||||||
i![attrs![At::Class => format!("styledIcon {}", logo)]],
|
attrs![At::Href => href],
|
||||||
|
styled_icon,
|
||||||
span![class!["itemText"], text]
|
span![class!["itemText"], text]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,8 @@ pub enum Icon {
|
|||||||
ArrowLeft,
|
ArrowLeft,
|
||||||
ArrowRight,
|
ArrowRight,
|
||||||
Cop,
|
Cop,
|
||||||
|
Message,
|
||||||
|
User,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Icon {
|
impl Icon {
|
||||||
@ -92,6 +94,8 @@ impl std::fmt::Display for Icon {
|
|||||||
Icon::ArrowLeft => "arrowLeft",
|
Icon::ArrowLeft => "arrowLeft",
|
||||||
Icon::ArrowRight => "arrowRight",
|
Icon::ArrowRight => "arrowRight",
|
||||||
Icon::Cop => "cop",
|
Icon::Cop => "cop",
|
||||||
|
Icon::Message => "message",
|
||||||
|
Icon::User => "user",
|
||||||
};
|
};
|
||||||
f.write_str(code)
|
f.write_str(code)
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@ pub type TokenId = i32;
|
|||||||
pub type IssueStatusId = i32;
|
pub type IssueStatusId = i32;
|
||||||
pub type InvitationId = i32;
|
pub type InvitationId = i32;
|
||||||
pub type Position = i32;
|
pub type Position = i32;
|
||||||
|
pub type MessageId = i32;
|
||||||
pub type EmailString = String;
|
pub type EmailString = String;
|
||||||
pub type UsernameString = String;
|
pub type UsernameString = String;
|
||||||
pub type TitleString = String;
|
pub type TitleString = String;
|
||||||
@ -506,8 +507,8 @@ pub struct UpdateIssuePayload {
|
|||||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
pub struct IssueAssignee {
|
pub struct IssueAssignee {
|
||||||
pub id: i32,
|
pub id: i32,
|
||||||
pub issue_id: i32,
|
pub issue_id: IssueId,
|
||||||
pub user_id: i32,
|
pub user_id: UserId,
|
||||||
pub created_at: NaiveDateTime,
|
pub created_at: NaiveDateTime,
|
||||||
pub updated_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)]
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
pub struct CreateCommentPayload {
|
pub struct CreateCommentPayload {
|
||||||
pub user_id: Option<UserId>,
|
pub user_id: Option<UserId>,
|
||||||
@ -541,7 +555,7 @@ pub struct CreateCommentPayload {
|
|||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
pub struct UpdateCommentPayload {
|
pub struct UpdateCommentPayload {
|
||||||
pub id: i32,
|
pub id: CommentId,
|
||||||
pub body: String,
|
pub body: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -719,4 +733,7 @@ pub enum WsMsg {
|
|||||||
AvatarUrlChanged(UserId, String),
|
AvatarUrlChanged(UserId, String),
|
||||||
ProfileUpdate(EmailString, UsernameString),
|
ProfileUpdate(EmailString, UsernameString),
|
||||||
ProfileUpdated,
|
ProfileUpdated,
|
||||||
|
|
||||||
|
// messages
|
||||||
|
Message(Message),
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user