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);
}
#projectPage > #projectBoardLists {
#projectPage > .rows > .row > .projectBoardLists {
display: flex;
margin: 26px -5px 0;
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;
flex-direction: column;
margin: 0 5px;
@ -99,7 +106,7 @@
background: var(--backgroundLightest);
}
#projectPage > #projectBoardLists > .list > .title {
#projectPage > .rows > .row > .projectBoardLists > .list > .title {
padding: 13px 10px 17px;
text-transform: uppercase;
color: var(--textMedium);
@ -109,22 +116,22 @@
text-overflow: ellipsis;
}
#projectPage > #projectBoardLists > .list > .title > .issuesCount {
#projectPage > .rows > .row > .projectBoardLists > .list > .title > .issuesCount {
text-transform: lowercase;
font-size: 13px;
}
#projectPage > #projectBoardLists > .list > .issues {
#projectPage > .rows > .row > .projectBoardLists > .list > .issues {
height: 100%;
padding: 0 5px;
}
#projectPage > #projectBoardLists > .list > .issues > .issueLink {
#projectPage > .rows > .row > .projectBoardLists > .list > .issues > .issueLink {
display: block;
margin-bottom: 5px;
}
#projectPage > #projectBoardLists > .list > .issues > .issueLink > .issue {
#projectPage > .rows > .row > .projectBoardLists > .list > .issues > .issueLink > .issue {
padding: 10px;
border-radius: 3px;
background: #fff;
@ -134,11 +141,11 @@
user-select: none;
}
#projectPage > #projectBoardLists > .list > .issues > .issueLink > .issue.hidden {
#projectPage > .rows > .row > .projectBoardLists > .list > .issues > .issueLink > .issue.hidden {
display: none;
}
#projectPage > #projectBoardLists > .list > .issues > .issueLink > .issue.isBeingDragged {
#projectPage > .rows > .row > .projectBoardLists > .list > .issues > .issueLink > .issue.isBeingDragged {
transform: rotate(3deg);
/*box-shadow: 5px 10px 30px 0 rgba(9, 30, 66, 0.15);*/
position: absolute;
@ -148,48 +155,48 @@
width: 90px;
}
#projectPage > #projectBoardLists > .list > .issues > .issueLink > .issue:hover {
#projectPage > .rows > .row > .projectBoardLists > .list > .issues > .issueLink > .issue:hover {
background: var(--backgroundLight);
}
#projectPage > #projectBoardLists > .list > .issues > .issueLink > .issue > .title {
#projectPage > .rows > .row > .projectBoardLists > .list > .issues > .issueLink > .issue > .title {
padding-bottom: 11px;
font-size: 15px;
}
@media (max-width: 1100px) {
#projectPage > #projectBoardLists > .list > .issues > .issueLink > .issue {
#projectPage > .rows > .row > .projectBoardLists > .list > .issues > .issueLink > .issue {
padding: 10px 8px;
}
#projectPage > #projectBoardLists > .list > .issues > .issueLink > .issue > .title {
#projectPage > .projectBoardLists > .list > .issues > .issueLink > .issue > .title {
font-size: 14.5px
}
}
#projectPage > #projectBoardLists > .list > .issues > .issueLink > .issue > .bottom {
#projectPage > .rows > .row > .projectBoardLists > .list > .issues > .issueLink > .issue > .bottom {
display: flex;
justify-content: space-between;
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;
flex-direction: row-reverse;
margin-left: 2px;
}
#projectPage > #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 > .assigneeAvatar,
#projectPage > .rows > .row > .projectBoardLists > .list > .issues > .issueLink > .issue > .bottom > .assignees > .styledAvatar {
margin-left: -2px;
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))) => {
model.issues.push(issue.clone());
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) => {
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> {
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
.issue_statuses
.iter()
.map(|is| project_issue_list(model, is))
.map(|issue_status| project_issue_list(model, issue_status, epic))
.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 {
PageContent::Project(project_page) => project_page,
_ => return empty![],
@ -171,7 +188,8 @@ fn project_issue_list(model: &Model, status: &jirs_data::IssueStatus) -> Node<Ms
.issues
.iter()
.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_text(issue, project_page.text_filter.as_str())
&& issue_filter_with_only_my(issue, project_page.only_my_filter, &model.user)