diff --git a/jirs-client/js/css/sidebar.css b/jirs-client/js/css/sidebar.css index dc7bdcd8..cd7a2fa9 100644 --- a/jirs-client/js/css/sidebar.css +++ b/jirs-client/js/css/sidebar.css @@ -67,7 +67,7 @@ nav#sidebar .linkItem { user-select: none; } -nav#sidebar .linkItem.notAllowed { +nav#sidebar .linkItem.notAllowed, nav#sidebar .linkItem.notAllowed > a { cursor: not-allowed; } @@ -75,17 +75,21 @@ nav#sidebar .linkItem:hover { background: var(--backgroundLight); } -nav#sidebar .linkItem > i.styledIcon { - margin-right: 15px; - font-size: 20px; -} - nav#sidebar .linkItem.active { color: var(--primary); background: var(--backgroundLight); } -nav#sidebar .linkItem > .linkText { +nav#sidebar .linkItem > a { + display: flex; +} + +nav#sidebar .linkItem > a > i.styledIcon { + margin-right: 15px; + font-size: 20px; +} + +nav#sidebar .linkItem > a > .linkText { padding-top: 2px; font-size: 14.7px; } diff --git a/jirs-client/src/model.rs b/jirs-client/src/model.rs index 473f4273..ca781b7a 100644 --- a/jirs-client/src/model.rs +++ b/jirs-client/src/model.rs @@ -3,13 +3,15 @@ use std::collections::hash_map::HashMap; use serde::{Deserialize, Serialize}; use uuid::Uuid; -use crate::HOST_URL; use jirs_data::*; +use crate::HOST_URL; + pub type ProjectId = i32; pub type StatusCode = u32; -#[derive(Serialize, Deserialize, Copy, Clone, Debug)] +#[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialOrd, PartialEq)] +#[serde(rename_all = "kebab-case")] pub enum Page { Project, ProjectSettings, @@ -17,6 +19,18 @@ pub enum Page { Register, } +impl Page { + pub fn to_path(&self) -> String { + match self { + Page::Project => "/board", + Page::ProjectSettings => "/project-settings", + Page::Login => "/login", + Page::Register => "/register", + } + .to_string() + } +} + #[derive(Serialize, Deserialize, Debug)] pub struct CreateCommentForm { pub fields: CreateCommentPayload, diff --git a/jirs-client/src/shared.rs b/jirs-client/src/shared.rs index 76f75f9f..313f4824 100644 --- a/jirs-client/src/shared.rs +++ b/jirs-client/src/shared.rs @@ -1,10 +1,12 @@ -use crate::model::{Icon, Model}; -use crate::Msg; -use jirs_data::FullProjectResponse; use seed::fetch::{FetchObject, FetchResult, ResponseWithDataResult}; use seed::{prelude::*, *}; use serde::Deserialize; +use jirs_data::FullProjectResponse; + +use crate::model::{Icon, Model, Page}; +use crate::Msg; + pub fn sidebar(model: &Model) -> Node { let project_info = match model.project.as_ref() { Some(project) => li![ @@ -28,25 +30,34 @@ pub fn sidebar(model: &Model) -> Node { id!["sidebar"], ul![ project_info, - sidebar_link_item(model, "Kanban Board", Icon::Board, "/board"), + sidebar_link_item(model, "Kanban Board", Icon::Board, Some(Page::Project)), sidebar_link_item( model, "Project settings", Icon::Settings, - "/project-settings" + Some(Page::ProjectSettings) ), - li![divider()] + li![divider()], + sidebar_link_item(model, "Releases", Icon::Shipping, None), + sidebar_link_item(model, "Issue and Filters", Icon::Issues, None), + sidebar_link_item(model, "Pages", Icon::Page, None), + sidebar_link_item(model, "Reports", Icon::Reports, None), + sidebar_link_item(model, "Components", Icon::Component, None), ] ] } -fn sidebar_link_item(_model: &Model, name: &str, icon: Icon, path: &str) -> Node { - let item_class = match path { - "" => format!("linkItem notAllowed {}", icon), - _ => format!("linkItem {}", icon), +fn sidebar_link_item(model: &Model, name: &str, icon: Icon, page: Option) -> Node { + let path = page.map(|ref p| p.to_path()).unwrap_or_default(); + let mut class_list = vec!["linkItem".to_string(), icon.to_string()]; + let item_class = if let None = page { + class_list.push("notAllowed".to_string()) }; + if Some(model.page) == page { + class_list.push("active".to_string()); + } li![ - attrs![At::Class => item_class], + attrs![At::Class => class_list.join(" ")], a![ attrs![At::Href => path], i![attrs![At::Class => format!("styledIcon {}", icon)], ""], diff --git a/react-client/src/api/index.ts b/react-client/src/api/index.ts index 880c71cc..fa592be3 100644 --- a/react-client/src/api/index.ts +++ b/react-client/src/api/index.ts @@ -9,7 +9,7 @@ export interface RequestBody { method?: string, } -export const endpoint = (): string => `http://localhost:3000`; +export const endpoint = (): string => `http://localhost:5000`; export const getContentType = (method, form) => method === 'GET' || form instanceof FormData diff --git a/react-client/src/shared/utils/api.js b/react-client/src/shared/utils/api.js index 8bd74cd8..055006f2 100644 --- a/react-client/src/shared/utils/api.js +++ b/react-client/src/shared/utils/api.js @@ -6,7 +6,7 @@ import { objectToQueryString } from 'shared/utils/url'; import { getStoredAuthToken, removeStoredAuthToken } from 'shared/utils/authToken'; const defaults = { - baseURL: process.env.API_URL || 'http://localhost:3000', + baseURL: process.env.API_URL || 'http://localhost:5000', headers: () => ({ 'Content-Type': 'application/json', Authorization: getStoredAuthToken() ? `Bearer ${ getStoredAuthToken() }` : undefined,