Commit ff7bab37 authored by Phil Hughes's avatar Phil Hughes

When moving to done & the issue belongs to more than 1 board it asks if user...

When moving to done & the issue belongs to more than 1 board it asks if user wants to remove from all the boards
Can filter issues by author, assignee & milestones
parent f330585a
......@@ -11,9 +11,9 @@ $ =>
new Vue
el: '#board-app'
data:
boards: BoardsStore.state
state: BoardsStore.state
ready: ->
service
.all()
.then (resp) ->
BoardsStore.state.push(board) for board in resp.data
BoardsStore.state.boards.push(board) for board in resp.data
......@@ -2,7 +2,7 @@ Board = Vue.extend
props:
board: Object
data: ->
dragging: BoardsStore.dragging
filters: BoardsStore.state.filters
methods:
clearSearch: ->
this.query = ''
......
BoardDelete = Vue.extend
props:
boardId: Number
Vue.component 'board-delete', BoardDelete
......@@ -2,8 +2,38 @@ BoardList = Vue.extend
props:
disabled: Boolean
boardId: [Number, String]
filters: Object
issues: Array
query: String
data: ->
scrollOffset: 20
loadMore: false
computed:
newDone: -> BoardsStore.state.done
methods:
listHeight: -> this.$els.list.getBoundingClientRect().height
scrollHeight: -> this.$els.list.scrollHeight
scrollTop: -> this.$els.list.scrollTop + this.listHeight()
loadFromLastId: ->
this.loadMore = true
setTimeout =>
this.loadMore = false
, 2000
customFilter: (issue) ->
returnIssue = issue
if this.filters.author?.id
if not issue.author? or issue.author?.id != this.filters.author.id
returnIssue = null
if this.filters.assignee?.id
if not issue.assignee? or issue.assignee?.id != this.filters.assignee.id
returnIssue = null
if this.filters.milestone?.id
if not issue.milestone? or issue.milestone?.id != this.filters.milestone.id
returnIssue = null
return returnIssue
ready: ->
Sortable.create this.$els.list,
group: 'issues'
......@@ -26,4 +56,9 @@ BoardList = Vue.extend
onUpdate: (e) ->
console.log e.newIndex, e.oldIndex
# Scroll event on list to load more
this.$els.list.onscroll = =>
if (this.scrollTop() > this.scrollHeight() - this.scrollOffset) and !this.loadMore
this.loadFromLastId()
Vue.component('board-list', BoardList)
IssueDone = Vue.extend
props:
done: Object
Vue.component('issue-done', IssueDone)
@BoardsStore =
state: []
state:
boards: []
done: {}
filters:
author: {}
assignee: {}
milestone: {}
moveBoard: (oldIndex, newIndex) ->
boardFrom = _.find BoardsStore.state, (board) ->
boardFrom = _.find BoardsStore.state.boards, (board) ->
board.index is oldIndex
service.updateBoard(boardFrom.id, newIndex)
boardTo = _.find BoardsStore.state, (board) ->
boardTo = _.find BoardsStore.state.boards, (board) ->
board.index is newIndex
boardFrom.index = newIndex
......@@ -15,12 +21,13 @@
else
boardTo.index++
moveCardToBoard: (boardFromId, boardToId, issueId, toIndex) ->
boardFrom = _.find BoardsStore.state, (board) ->
boardFrom = _.find BoardsStore.state.boards, (board) ->
board.id is boardFromId
boardTo = _.find BoardsStore.state, (board) ->
boardTo = _.find BoardsStore.state.boards, (board) ->
board.id is boardToId
issue = _.find boardFrom.issues, (issue) ->
issue.id is issueId
issueBoards = BoardsStore.getBoardsForIssue(issue)
# Remove the issue from old board
boardFrom.issues = _.reject boardFrom.issues, (issue) ->
......@@ -29,13 +36,22 @@
# Add to new boards issues
boardTo.issues.splice(toIndex, 0, issue)
# If going to done - remove label
if boardTo.id is 'done' and boardFrom.id != 'backlog'
if boardTo.id is 'done'
Vue.set(BoardsStore.state.done, 'board', boardFrom)
Vue.set(BoardsStore.state.done, 'issue', issue)
Vue.set(BoardsStore.state.done, 'boards', issueBoards)
else if boardTo.id is 'done' and boardFrom.id != 'backlog'
issue.labels = _.reject issue.labels, (label) ->
label.title is boardFrom.title
else if boardTo.label?
else
if boardTo.label?
foundLabel = _.find issue.labels, (label) ->
label.title is boardTo.label.title
unless foundLabel?
issue.labels.push(boardTo.label)
getBoardsForIssue: (issue) ->
_.filter BoardsStore.state.boards, (board) ->
foundIssue = _.find board.issues, (boardIssue) ->
issue?.id == boardIssue?.id
foundIssue?
......@@ -33,6 +33,7 @@
.board {
min-width: 400px;
max-width: 400px;
height: 100%;
padding-right: ($gl-padding / 2);
padding-left: ($gl-padding / 2);
......@@ -103,11 +104,27 @@
}
}
.board-delete {
margin-right: 10px;
padding: 0;
color: $gray-darkest;
background-color: transparent;
border: 0;
&:hover {
color: $gl-link-color;
}
}
.board-list {
flex: 1;
margin: 0;
padding: 5px;
overflow: scroll;
&.is-marking-done {
flex: 0 0 auto;
}
}
.is-ghost {
......@@ -154,3 +171,37 @@
margin-right: 8px;
font-weight: 500;
}
.board-done {
flex: 1;
padding: 10px 18px;
color: #8c8c8c;
background-color: #fff;
border-top: 1px solid $border-color;
> p {
margin: 0;
font-size: 1em;
}
}
.board-done-label-list {
margin: 10px 0 10px 30px;
padding: 0;
color: #333;
list-style: none;
> li:not(:last-child) {
margin-bottom: 5px;
}
.label {
display: inline-block;
position: relative;
top: 2px;
width: 16px;
height: 16px;
margin-right: 5px;
border-radius: $border-radius-default;
}
}
%board{ "inline-template" => true, "v-cloak" => true, "v-for" => "board in boards | orderBy 'index'", ":board" => "board" }
%board{ "inline-template" => true, "v-cloak" => true, "v-for" => "board in state.boards | orderBy 'index'", ":board" => "board" }
.board{ ":class" => "{ 'is-draggable': !isPreset }" }
.board-inner
%header.board-inner-container.board-header{ ":class" => "{ 'has-border': board.label }", ":style" => "{ borderTopColor: board.label.backgroundColor }" }
......@@ -6,6 +6,11 @@
{{ board.title }}
%span.pull-right
{{ board.issues.length }}
%board-delete{ "inline-template" => true, "v-if" => "!isPreset" }
%button.board-delete.has-tooltip.pull-right{ type: "button", title: "Delete board", data: { placement: "bottom" } }
%span.sr-only
Delete board
= icon("trash")
.board-inner-container.board-search-container{ "v-if" => "board.search" }
%input.form-control{ type: "text", placeholder: "Search issues", "v-model" => "query" }
= icon("search", class: "board-search-icon", "v-show" => "!query")
......@@ -13,6 +18,20 @@
%span.sr-only
Clear search
= icon("times", class: "board-search-clear")
%board-list{ "inline-template" => true, ":board-id" => "board.id", ":issues" => "board.issues", ":disabled" => "#{current_user.nil?}", ":query" => "query" }
%ul.board-list{ "v-el:list" => true, ":data-board" => "boardId" }
%board-list{ "inline-template" => true, ":board-id" => "board.id", ":issues" => "board.issues", ":disabled" => "#{current_user.nil?}", ":query" => "query", ":filters" => "filters" }
%ul.board-list{ "v-el:list" => true, ":data-board" => "boardId", ":class" => "{ 'is-marking-done': boardId == 'done' && newDone.board }" }
= render "projects/boards/components/card"
%issue-done{ "inline-template" => true, ":done" => "newDone", "v-if" => "boardId == 'done' && newDone.board" }
.board-done
%p
This issue is currently in the following lists:
%ul.board-done-label-list
%li{ "v-for" => "board in done.boards" }
%span.label{ ":style" => "{ 'background-color': board.label.backgroundColor, 'color': board.label.color }" }
{{ board.title }}
%p
Moving it to Done will remove it from all lists and close the issue.
%button.btn.btn-gray.btn-block.prepend-top-10{ type: "button" }
Remove from all lists and close
%button.btn.btn-gray.btn-block{ type: "button" }
Remove from {{ done.board.title }} list
%li.card{ ":data-issue" => "issue.id", "v-for" => "issue in issues | filterBy query in 'title'" }
%li.card{ ":data-issue" => "issue.id", "v-for" => "issue in issues | filterBy query in 'title' | filterBy customFilter" }
%h4.card-title
%a{ href: "#", ":title" => "issue.title" }
{{ issue.title }}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment