Display epics as boards

This commit is contained in:
Adrian Woźniak 2020-08-11 23:11:55 +02:00
parent 38654fca85
commit 316d315bea
3 changed files with 57 additions and 27 deletions

View File

@ -83,13 +83,20 @@
color: var(--textMedium); color: var(--textMedium);
} }
#projectPage > #projectBoardLists { #projectPage > .rows > .row > .projectBoardLists {
display: flex; display: flex;
margin: 26px -5px 0; margin: 26px -5px 0;
position: relative; position: relative;
} }
#projectPage > #projectBoardLists > .list { #projectPage > .rows > .row > .rowName {
position: relative;
color: var(--textDark);
font-family: var(--font-regular);
margin: 26px -5px 0;
}
#projectPage > .rows > .row > .projectBoardLists > .list {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
margin: 0 5px; margin: 0 5px;
@ -99,7 +106,7 @@
background: var(--backgroundLightest); background: var(--backgroundLightest);
} }
#projectPage > #projectBoardLists > .list > .title { #projectPage > .rows > .row > .projectBoardLists > .list > .title {
padding: 13px 10px 17px; padding: 13px 10px 17px;
text-transform: uppercase; text-transform: uppercase;
color: var(--textMedium); color: var(--textMedium);
@ -109,22 +116,22 @@
text-overflow: ellipsis; text-overflow: ellipsis;
} }
#projectPage > #projectBoardLists > .list > .title > .issuesCount { #projectPage > .rows > .row > .projectBoardLists > .list > .title > .issuesCount {
text-transform: lowercase; text-transform: lowercase;
font-size: 13px; font-size: 13px;
} }
#projectPage > #projectBoardLists > .list > .issues { #projectPage > .rows > .row > .projectBoardLists > .list > .issues {
height: 100%; height: 100%;
padding: 0 5px; padding: 0 5px;
} }
#projectPage > #projectBoardLists > .list > .issues > .issueLink { #projectPage > .rows > .row > .projectBoardLists > .list > .issues > .issueLink {
display: block; display: block;
margin-bottom: 5px; margin-bottom: 5px;
} }
#projectPage > #projectBoardLists > .list > .issues > .issueLink > .issue { #projectPage > .rows > .row > .projectBoardLists > .list > .issues > .issueLink > .issue {
padding: 10px; padding: 10px;
border-radius: 3px; border-radius: 3px;
background: #fff; background: #fff;
@ -134,11 +141,11 @@
user-select: none; user-select: none;
} }
#projectPage > #projectBoardLists > .list > .issues > .issueLink > .issue.hidden { #projectPage > .rows > .row > .projectBoardLists > .list > .issues > .issueLink > .issue.hidden {
display: none; display: none;
} }
#projectPage > #projectBoardLists > .list > .issues > .issueLink > .issue.isBeingDragged { #projectPage > .rows > .row > .projectBoardLists > .list > .issues > .issueLink > .issue.isBeingDragged {
transform: rotate(3deg); transform: rotate(3deg);
/*box-shadow: 5px 10px 30px 0 rgba(9, 30, 66, 0.15);*/ /*box-shadow: 5px 10px 30px 0 rgba(9, 30, 66, 0.15);*/
position: absolute; position: absolute;
@ -148,48 +155,48 @@
width: 90px; width: 90px;
} }
#projectPage > #projectBoardLists > .list > .issues > .issueLink > .issue:hover { #projectPage > .rows > .row > .projectBoardLists > .list > .issues > .issueLink > .issue:hover {
background: var(--backgroundLight); background: var(--backgroundLight);
} }
#projectPage > #projectBoardLists > .list > .issues > .issueLink > .issue > .title { #projectPage > .rows > .row > .projectBoardLists > .list > .issues > .issueLink > .issue > .title {
padding-bottom: 11px; padding-bottom: 11px;
font-size: 15px; font-size: 15px;
} }
@media (max-width: 1100px) { @media (max-width: 1100px) {
#projectPage > #projectBoardLists > .list > .issues > .issueLink > .issue { #projectPage > .rows > .row > .projectBoardLists > .list > .issues > .issueLink > .issue {
padding: 10px 8px; padding: 10px 8px;
} }
#projectPage > #projectBoardLists > .list > .issues > .issueLink > .issue > .title { #projectPage > .projectBoardLists > .list > .issues > .issueLink > .issue > .title {
font-size: 14.5px font-size: 14.5px
} }
} }
#projectPage > #projectBoardLists > .list > .issues > .issueLink > .issue > .bottom { #projectPage > .rows > .row > .projectBoardLists > .list > .issues > .issueLink > .issue > .bottom {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
} }
#projectPage > #projectBoardLists > .list > .issues > .issueLink > .issue > .bottom > div { #projectPage > .rows > .row > .projectBoardLists > .list > .issues > .issueLink > .issue > .bottom > div {
} }
#projectPage > #projectBoardLists > .list > .issues > .issueLink > .issue > .bottom > div > .issueTypeIcon { #projectPage > .rows > .row > .projectBoardLists > .list > .issues > .issueLink > .issue > .bottom > div > .issueTypeIcon {
} }
#projectPage > #projectBoardLists > .list > .issues > .issueLink > .issue > .bottom > div > .issuePriorityIcon { #projectPage > .rows > .row > .projectBoardLists > .list > .issues > .issueLink > .issue > .bottom > div > .issuePriorityIcon {
} }
#projectPage > #projectBoardLists > .list > .issues > .issueLink > .issue > .bottom > .assignees { #projectPage > .rows > .row > .projectBoardLists > .list > .issues > .issueLink > .issue > .bottom > .assignees {
display: flex; display: flex;
flex-direction: row-reverse; flex-direction: row-reverse;
margin-left: 2px; margin-left: 2px;
} }
#projectPage > #projectBoardLists > .list > .issues > .issueLink > .issue > .bottom > .assignees > .assigneeAvatar, #projectPage > .rows > .row > .projectBoardLists > .list > .issues > .issueLink > .issue > .bottom > .assignees > .assigneeAvatar,
#projectPage > #projectBoardLists > .list > .issues > .issueLink > .issue > .bottom > .assignees > .styledAvatar { #projectPage > .rows > .row > .projectBoardLists > .list > .issues > .issueLink > .issue > .bottom > .assignees > .styledAvatar {
margin-left: -2px; margin-left: -2px;
box-shadow: 0 0 0 2px #fff; box-shadow: 0 0 0 2px #fff;
} }

View File

@ -163,11 +163,16 @@ pub fn update(msg: &Msg, model: &mut crate::model::Model, orders: &mut impl Orde
} }
}; };
} }
Msg::WebSocketChange(WebSocketChanged::WsMsg(WsMsg::IssueCreated(issue))) => { Msg::WebSocketChange(WebSocketChanged::WsMsg(WsMsg::IssueCreated(issue))) => {
model.issues.push(issue.clone()); model.issues.push(issue.clone());
orders.skip().send_msg(Msg::ModalDropped); orders.skip().send_msg(Msg::ModalDropped);
} }
Msg::WebSocketChange(WebSocketChanged::WsMsg(WsMsg::EpicCreated(_))) => {
orders.skip().send_msg(Msg::ModalDropped);
}
Msg::StrInputChanged(FieldId::AddIssueModal(IssueFieldId::Description), value) => { Msg::StrInputChanged(FieldId::AddIssueModal(IssueFieldId::Description), value) => {
modal.description = Some(value.clone()); modal.description = Some(value.clone());
} }

View File

@ -140,15 +140,32 @@ fn avatars_filters(model: &Model) -> Node<Msg> {
} }
fn project_board_lists(model: &Model) -> Node<Msg> { fn project_board_lists(model: &Model) -> Node<Msg> {
let mut rows: Vec<Option<&Epic>> = vec![None];
for epic in model.epics.iter() {
rows.push(Some(epic));
}
let rows: Vec<Node<Msg>> = rows
.into_iter()
.map(|epic| {
let title = epic
.map(|epic| div![C!["rowName"], epic.name.as_str()])
.unwrap_or_else(|| empty![]);
let columns: Vec<Node<Msg>> = model let columns: Vec<Node<Msg>> = model
.issue_statuses .issue_statuses
.iter() .iter()
.map(|is| project_issue_list(model, is)) .map(|issue_status| project_issue_list(model, issue_status, epic))
.collect(); .collect();
div![id!["projectBoardLists"], columns] div![C!["row"], title, div![C!["projectBoardLists"], columns]]
})
.collect();
div![C!["rows"], rows]
} }
fn project_issue_list(model: &Model, status: &jirs_data::IssueStatus) -> Node<Msg> { fn project_issue_list(
model: &Model,
status: &jirs_data::IssueStatus,
epic: Option<&jirs_data::Epic>,
) -> Node<Msg> {
let project_page = match &model.page_content { let project_page = match &model.page_content {
PageContent::Project(project_page) => project_page, PageContent::Project(project_page) => project_page,
_ => return empty![], _ => return empty![],
@ -171,7 +188,8 @@ fn project_issue_list(model: &Model, status: &jirs_data::IssueStatus) -> Node<Ms
.issues .issues
.iter() .iter()
.filter(|issue| { .filter(|issue| {
issue_filter_status(issue, status) issue.epic_id == epic.map(|epic| epic.id)
&& issue_filter_status(issue, status)
&& issue_filter_with_avatars(issue, &project_page.active_avatar_filters) && issue_filter_with_avatars(issue, &project_page.active_avatar_filters)
&& issue_filter_with_text(issue, project_page.text_filter.as_str()) && issue_filter_with_text(issue, project_page.text_filter.as_str())
&& issue_filter_with_only_my(issue, project_page.only_my_filter, &model.user) && issue_filter_with_only_my(issue, project_page.only_my_filter, &model.user)