Add epics page
This commit is contained in:
parent
c06c936118
commit
8ae4cc22ba
@ -64,8 +64,8 @@ https://git.sr.ht/~tsumanu/jirs
|
|||||||
* [ ] Insert Code in Rich Text Editor
|
* [ ] Insert Code in Rich Text Editor
|
||||||
* [X] Code syntax
|
* [X] Code syntax
|
||||||
* [X] Personal settings to choose MDE (Markdown Editor) or RTE
|
* [X] Personal settings to choose MDE (Markdown Editor) or RTE
|
||||||
* [ ] Issues and filters view
|
* [X] Issues and filters view
|
||||||
* [ ] Issues and filters working filters
|
* [X] Issues and filters working filters
|
||||||
|
|
||||||
## How to run it
|
## How to run it
|
||||||
|
|
||||||
|
42
jirs-client/js/css/epicsPage.scss
Normal file
42
jirs-client/js/css/epicsPage.scss
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
#epics {
|
||||||
|
> section {
|
||||||
|
> h1 {
|
||||||
|
font-family: var(--font-bold);
|
||||||
|
}
|
||||||
|
|
||||||
|
> .description {
|
||||||
|
font-family: var(--font-regular);
|
||||||
|
margin: {
|
||||||
|
top: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
> ul.epicsList {
|
||||||
|
margin: 0;
|
||||||
|
margin: {
|
||||||
|
top: 5px;
|
||||||
|
}
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
|
||||||
|
> li.epic {
|
||||||
|
padding: 0;
|
||||||
|
margin: {
|
||||||
|
top: 5px;
|
||||||
|
bottom: 5px;
|
||||||
|
};
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
|
> .epicName {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
> .date {
|
||||||
|
width: 250px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -36,3 +36,4 @@
|
|||||||
@import "css/reports.scss";
|
@import "css/reports.scss";
|
||||||
@import "css/profile.scss";
|
@import "css/profile.scss";
|
||||||
@import "css/issuesAndFilters.scss";
|
@import "css/issuesAndFilters.scss";
|
||||||
|
@import "css/epicsPage.scss";
|
||||||
|
@ -262,9 +262,7 @@ fn update(msg: Msg, model: &mut model::Model, orders: &mut impl Orders<Msg>) {
|
|||||||
Page::Profile => pages::profile_page::update(msg, model, orders),
|
Page::Profile => pages::profile_page::update(msg, model, orders),
|
||||||
Page::Reports => pages::reports_page::update(msg, model, orders),
|
Page::Reports => pages::reports_page::update(msg, model, orders),
|
||||||
Page::IssuesAndFilters => pages::issues_and_filters::update(msg, model, orders),
|
Page::IssuesAndFilters => pages::issues_and_filters::update(msg, model, orders),
|
||||||
}
|
Page::Epics => pages::epics_page::update(msg, model, orders),
|
||||||
if cfg!(features = "print-model") {
|
|
||||||
log::debug!("{:?}", model);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -285,6 +283,7 @@ fn view(model: &model::Model) -> Node<Msg> {
|
|||||||
Page::Profile => pages::profile_page::view(model),
|
Page::Profile => pages::profile_page::view(model),
|
||||||
Page::Reports => pages::reports_page::view(model),
|
Page::Reports => pages::reports_page::view(model),
|
||||||
Page::IssuesAndFilters => pages::issues_and_filters::view(model),
|
Page::IssuesAndFilters => pages::issues_and_filters::view(model),
|
||||||
|
Page::Epics => pages::epics_page::view(model),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -317,6 +316,7 @@ fn resolve_page(url: Url) -> Option<Page> {
|
|||||||
_ => return None,
|
_ => return None,
|
||||||
},
|
},
|
||||||
"issues-and-filters" => Page::IssuesAndFilters,
|
"issues-and-filters" => Page::IssuesAndFilters,
|
||||||
|
"epics" => Page::Epics,
|
||||||
_ => Page::Project,
|
_ => Page::Project,
|
||||||
};
|
};
|
||||||
Some(page)
|
Some(page)
|
||||||
|
@ -7,6 +7,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::components::styled_select::StyledSelectState;
|
use crate::components::styled_select::StyledSelectState;
|
||||||
|
use crate::pages::epics_page::EpicsPage;
|
||||||
use crate::pages::invite_page::InvitePage;
|
use crate::pages::invite_page::InvitePage;
|
||||||
use crate::pages::issues_and_filters::IssuesAndFiltersPage;
|
use crate::pages::issues_and_filters::IssuesAndFiltersPage;
|
||||||
use crate::pages::profile_page::model::ProfilePage;
|
use crate::pages::profile_page::model::ProfilePage;
|
||||||
@ -73,6 +74,7 @@ pub enum Page {
|
|||||||
// epic
|
// epic
|
||||||
DeleteEpic(EpicId),
|
DeleteEpic(EpicId),
|
||||||
EditEpic(EpicId),
|
EditEpic(EpicId),
|
||||||
|
Epics,
|
||||||
// issue
|
// issue
|
||||||
EditIssue(EpicId),
|
EditIssue(EpicId),
|
||||||
AddIssue,
|
AddIssue,
|
||||||
@ -105,6 +107,7 @@ impl Page {
|
|||||||
Page::Users => "/users".to_string(),
|
Page::Users => "/users".to_string(),
|
||||||
Page::Profile => "/profile".to_string(),
|
Page::Profile => "/profile".to_string(),
|
||||||
Page::Reports => "/reports".to_string(),
|
Page::Reports => "/reports".to_string(),
|
||||||
|
Page::Epics => "/epics".to_string(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,6 +197,7 @@ pub enum PageContent {
|
|||||||
Profile(Box<ProfilePage>),
|
Profile(Box<ProfilePage>),
|
||||||
Reports(Box<ReportsPage>),
|
Reports(Box<ReportsPage>),
|
||||||
IssuesAndFilters(Box<IssuesAndFiltersPage>),
|
IssuesAndFilters(Box<IssuesAndFiltersPage>),
|
||||||
|
Epics(Box<EpicsPage>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
7
jirs-client/src/pages/epics_page/mod.rs
Normal file
7
jirs-client/src/pages/epics_page/mod.rs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
pub use model::*;
|
||||||
|
pub use update::*;
|
||||||
|
pub use view::*;
|
||||||
|
|
||||||
|
mod model;
|
||||||
|
mod update;
|
||||||
|
mod view;
|
8
jirs-client/src/pages/epics_page/model.rs
Normal file
8
jirs-client/src/pages/epics_page/model.rs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#[derive(Debug)]
|
||||||
|
pub struct EpicsPage {}
|
||||||
|
|
||||||
|
impl EpicsPage {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {}
|
||||||
|
}
|
||||||
|
}
|
30
jirs-client/src/pages/epics_page/update.rs
Normal file
30
jirs-client/src/pages/epics_page/update.rs
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
use seed::app::Orders;
|
||||||
|
|
||||||
|
use crate::model::{Model, Page, PageContent};
|
||||||
|
use crate::ws::board_load;
|
||||||
|
use crate::{Msg, OperationKind, ResourceKind};
|
||||||
|
|
||||||
|
pub fn update(msg: Msg, model: &mut crate::model::Model, orders: &mut impl Orders<Msg>) {
|
||||||
|
if model.user.is_none() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if matches!(model.page, Page::IssuesAndFilters)
|
||||||
|
&& !matches!(model.page_content, PageContent::IssuesAndFilters(..))
|
||||||
|
{
|
||||||
|
build_page_content(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
match msg {
|
||||||
|
Msg::ResourceChanged(ResourceKind::Auth, OperationKind::SingleLoaded, Some(_))
|
||||||
|
| Msg::ChangePage(Page::Epics) => {
|
||||||
|
board_load(model, orders);
|
||||||
|
build_page_content(model);
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_page_content(model: &mut Model) {
|
||||||
|
model.page_content = PageContent::Epics(Box::new(super::EpicsPage::new()));
|
||||||
|
}
|
57
jirs-client/src/pages/epics_page/view.rs
Normal file
57
jirs-client/src/pages/epics_page/view.rs
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
use chrono::NaiveDateTime;
|
||||||
|
use seed::prelude::*;
|
||||||
|
use seed::*;
|
||||||
|
|
||||||
|
use crate::model::Model;
|
||||||
|
use crate::shared::inner_layout;
|
||||||
|
use crate::Msg;
|
||||||
|
|
||||||
|
pub fn view(model: &Model) -> Node<Msg> {
|
||||||
|
let epics: Vec<Node<Msg>> = model
|
||||||
|
.epics
|
||||||
|
.iter()
|
||||||
|
.map(|epic| {
|
||||||
|
li![
|
||||||
|
C!["epic"],
|
||||||
|
div![C!["epicName"], &epic.name],
|
||||||
|
div![
|
||||||
|
C!["date"],
|
||||||
|
div![
|
||||||
|
C!["startsAt"],
|
||||||
|
span!["Stats At:"],
|
||||||
|
span![epic
|
||||||
|
.starts_at
|
||||||
|
.as_ref()
|
||||||
|
.map(|d| format!("{}", d.format("%e %B %Y")))
|
||||||
|
.unwrap_or_default()]
|
||||||
|
],
|
||||||
|
div![
|
||||||
|
C!["endsAt"],
|
||||||
|
span!["Ends At: "],
|
||||||
|
span![epic
|
||||||
|
.ends_at
|
||||||
|
.as_ref()
|
||||||
|
.map(|d| format!("{}", d.format("%e %B %Y")))
|
||||||
|
.unwrap_or_default()]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
inner_layout(
|
||||||
|
model,
|
||||||
|
"epics",
|
||||||
|
&[section![
|
||||||
|
h1!["Epics"],
|
||||||
|
p!["Epics and issues grouped in them"],
|
||||||
|
ul![C!["epicsList"], epics]
|
||||||
|
]],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn date_field(name: &str, date: Option<&NaiveDateTime>) -> Node<Msg> {
|
||||||
|
match date {
|
||||||
|
_ => Node::Empty,
|
||||||
|
}
|
||||||
|
}
|
@ -1,3 +1,4 @@
|
|||||||
|
pub mod epics_page;
|
||||||
pub mod invite_page;
|
pub mod invite_page;
|
||||||
pub mod issues_and_filters;
|
pub mod issues_and_filters;
|
||||||
pub mod profile_page;
|
pub mod profile_page;
|
||||||
|
@ -54,16 +54,14 @@ pub fn render(model: &Model) -> Node<Msg> {
|
|||||||
sidebar_link_item(model, "Kanban Board", Icon::Board, Some(Page::Project)),
|
sidebar_link_item(model, "Kanban Board", Icon::Board, Some(Page::Project)),
|
||||||
project_settings(model),
|
project_settings(model),
|
||||||
li![divider()],
|
li![divider()],
|
||||||
sidebar_link_item(model, "Releases", Icon::Shipping, None),
|
|
||||||
sidebar_link_item(
|
sidebar_link_item(
|
||||||
model,
|
model,
|
||||||
"Issue and Filters",
|
"Issue and Filters",
|
||||||
Icon::Issues,
|
Icon::Issues,
|
||||||
Some(Page::IssuesAndFilters)
|
Some(Page::IssuesAndFilters)
|
||||||
),
|
),
|
||||||
sidebar_link_item(model, "Pages", Icon::Page, None),
|
|
||||||
sidebar_link_item(model, "Reports", Icon::Reports, Some(Page::Reports)),
|
sidebar_link_item(model, "Reports", Icon::Reports, Some(Page::Reports)),
|
||||||
sidebar_link_item(model, "Components", Icon::Component, None),
|
sidebar_link_item(model, "Epics", Icon::Component, Some(Page::Epics)),
|
||||||
users_link(model)
|
users_link(model)
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
Loading…
Reference in New Issue
Block a user