Commit 8e041957 authored by Phil Hughes's avatar Phil Hughes

Moved to ES6

parent 61fa7b75
#= require vue
#= require vue-resource
#= require Sortable
#= require_tree ./stores
#= require_tree ./services
#= require_tree ./components
$ =>
@service = new BoardService($('#board-app').data('endpoint'))
new Vue
el: '#board-app'
data:
state: BoardsStore.state
ready: ->
service
.all()
.then (resp) ->
BoardsStore.state.boards.push(board) for board in resp.data
//= require vue
//= require vue-resource
//= require Sortable
//= require_tree ./stores
//= require_tree ./services
//= require_tree ./components
$(function () {
window.service = new BoardService($('#board-app').data('endpoint'));
new Vue({
el: '#board-app',
data: {
state: BoardsStore.state
},
ready: function () {
service.all()
.then((resp) => {
resp.data.forEach((board) => {
BoardsStore.state.boards.push(board);
});
});
}
});
});
Board = Vue.extend
props:
board: Object
data: ->
filters: BoardsStore.state.filters
methods:
clearSearch: ->
this.query = ''
computed:
isPreset: ->
typeof this.board.id != 'number'
ready: ->
this.sortable = Sortable.create this.$el.parentNode,
group: 'boards'
animation: 150
draggable: '.is-draggable'
forceFallback: true
fallbackClass: 'is-dragging'
ghostClass: 'is-ghost'
onUpdate: (e) ->
BoardsStore.moveBoard(e.oldIndex + 1, e.newIndex + 1)
beforeDestroy: ->
this.sortable.destroy()
Vue.component('board', Board)
(() => {
const Board = Vue.extend({
props: {
board: Object
},
data: () => {
return {
filters: BoardsStore.state.filters
};
},
methods: {
clearSearch: function () {
this.query = '';
}
},
computed: {
isPreset: function () {
typeof this.board.id !== 'number';
}
},
ready: function () {
this.sortable = Sortable.create(this.$el.parentNode, {
group: 'boards',
animation: 150,
draggable: '.is-draggable',
forceFallback: true,
fallbackClass: 'is-dragging',
ghostClass: 'is-ghost',
onUpdate: function (e) {
BoardsStore.moveBoard(e.oldIndex + 1, e.newIndex + 1);
}
});
},
beforeDestroy: function () {
this.sortable.destroy();
}
});
Vue.component('board', Board)
}());
BoardDelete = Vue.extend
props:
boardId: Number
methods:
deleteBoard: ->
$(this.$el).tooltip('destroy')
if confirm('Are you sure you want to delete this list?')
BoardsStore.removeBoard(this.boardId)
Vue.component 'board-delete', BoardDelete
(() => {
const BoardDelete = Vue.extend({
props: {
boardId: Number
},
methods: {
deleteBoard: function () {
$(this.$el).tooltip('destroy');
if (confirm('Are you sure you want to delete this list?')) {
BoardsStore.removeBoard(this.boardId);
}
}
}
});
Vue.component('board-delete', BoardDelete);
}());
BoardList = Vue.extend
props:
disabled: Boolean
boardId: [Number, String]
filters: Object
issues: Array
query: String
data: ->
scrollOffset: 20
loadMore: false
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: ->
this.sortable = Sortable.create this.$els.list,
group: 'issues'
disabled: this.disabled
scrollSensitivity: 150
scrollSpeed: 50
forceFallback: true
fallbackClass: 'is-dragging'
ghostClass: 'is-ghost'
onAdd: (e) ->
fromBoardId = e.from.getAttribute('data-board')
fromBoardId = parseInt(fromBoardId) || fromBoardId
toBoardId = e.to.getAttribute('data-board')
toBoardId = parseInt(toBoardId) || toBoardId
issueId = parseInt(e.item.getAttribute('data-issue'))
BoardsStore.moveCardToBoard(fromBoardId, toBoardId, issueId, e.newIndex)
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()
beforeDestroy: ->
this.sortable.destroy()
Vue.component('board-list', BoardList)
(() => {
const BoardList = Vue.extend({
props: {
disabled: Boolean,
boardId: [Number, String],
filters: Object,
issues: Array,
query: String
},
data: () => {
return {
scrollOffset: 20,
loadMore: false
};
},
methods: {
listHeight: function () {
return this.$els.list.getBoundingClientRect().height;
},
scrollHeight: function () {
return this.$els.list.scrollHeight;
},
scrollTop: function () {
return this.$els.list.scrollTop + this.listHeight();
},
loadFromLastId: function () {
this.loadMore = true;
setTimeout(() => {
this.loadMore = false;
}, 2000);
},
customFilter: function (issue) {
let returnIssue = issue;
if (this.filters.author && this.filters.author.id) {
if (!issue.author || issue.author.id !== this.filters.author.id) {
returnIssue = null;
}
}
if (this.filters.assignee && this.filters.assignee.id) {
if (!issue.assignee || issue.assignee.id !== this.filters.assignee.id) {
returnIssue = null;
}
}
if (this.filters.milestone && this.filters.milestone.id) {
if (!issue.milestone || issue.milestone.id !== this.filters.milestone.id) {
returnIssue = null;
}
}
return returnIssue;
}
},
ready: function () {
this.sortable = Sortable.create(this.$els.list, {
group: 'issues',
disabled: this.disabled,
scrollSensitivity: 150,
scrollSpeed: 50,
forceFallback: true,
fallbackClass: 'is-dragging',
ghostClass: 'is-ghost',
onAdd: (e) => {
let fromBoardId = e.from.getAttribute('data-board');
fromBoardId = parseInt(fromBoardId) || fromBoardId;
let toBoardId = e.to.getAttribute('data-board');
toBoardId = parseInt(toBoardId) || toBoardId;
const issueId = parseInt(e.item.getAttribute('data-issue'));
BoardsStore.moveCardToBoard(fromBoardId, toBoardId, issueId, e.newIndex);
},
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) && !this.loadMore) {
this.loadFromLastId();
}
};
},
beforeDestroy: function () {
this.sortable.destroy();
}
});
Vue.component('board-list', BoardList);
}());
class @BoardService
constructor: (@root) ->
Vue.http.options.root = @root
@resource = Vue.resource "#{@root}{/id}", {},
all:
method: 'GET'
url: 'all'
setCSRF: ->
Vue.http.headers.common['X-CSRF-Token'] = $.rails.csrfToken()
all: ->
@setCSRF()
@resource.all()
updateBoard: (id, index) ->
@setCSRF()
@resource.update { id: id }, { index: index }
class BoardService {
constructor (root) {
Vue.http.options.root = root;
this.resource = Vue.resource(`${root}{/id}`, {}, {
all: {
method: 'GET',
url: 'all'
}
});
}
setCSRF () {
Vue.http.headers.common['X-CSRF-Token'] = $.rails.csrfToken();
}
all () {
this.setCSRF();
return this.resource.all();
}
updateBoard (id, index) {
this.setCSRF();
return this.resource.update({ id: id }, { index: index });
}
};
@BoardsStore =
state:
boards: []
done: {}
filters:
author: {}
assignee: {}
milestone: {}
removeBoard: (id) ->
BoardsStore.state.boards = _.reject BoardsStore.state.boards, (board) ->
board.id is id
moveBoard: (oldIndex, newIndex) ->
boardFrom = _.find BoardsStore.state.boards, (board) ->
board.index is oldIndex
service.updateBoard(boardFrom.id, newIndex)
boardTo = _.find BoardsStore.state.boards, (board) ->
board.index is newIndex
boardFrom.index = newIndex
if newIndex > boardTo.index
boardTo.index--
else
boardTo.index++
moveCardToBoard: (boardFromId, boardToId, issueId, toIndex) ->
boardFrom = _.find BoardsStore.state.boards, (board) ->
board.id is boardFromId
boardTo = _.find BoardsStore.state.boards, (board) ->
board.id is boardToId
issue = _.find boardFrom.issues, (issue) ->
issue.id is issueId
issueTo = _.find boardTo.issues, (issue) ->
issue.id is issueId
issueBoards = BoardsStore.getBoardsForIssue(issue)
# Remove the issue from old board
boardFrom.issues = _.reject boardFrom.issues, (issue) ->
issue.id is issueId
# Add to new boards issues if it doesn't already exist
if issueTo?
issue = issueTo
else
boardTo.issues.splice(toIndex, 0, issue)
if boardTo.id is 'done' and boardFrom.id != 'backlog'
BoardsStore.removeIssueFromBoards(issue, issueBoards)
issue.labels = _.reject issue.labels, (label) ->
label.title is boardFrom.title
else
if boardTo.label?
BoardsStore.removeIssueFromBoard(issue, boardFrom)
foundLabel = _.find issue.labels, (label) ->
label.title is boardTo.title
unless foundLabel?
issue.labels.push(boardTo.label)
removeIssueFromBoards: (issue, boards) ->
boardLabels = _.map boards, (board) ->
board.label.title
boards.issues = _.each boards, (board) ->
board.issues = _.reject board.issues, (boardIssue) ->
issue.id is boardIssue.id
issue.labels = _.reject issue.labels, (label) ->
boardLabels.indexOf(label.title) != -1
removeIssueFromBoard: (issue, board) ->
issue.labels = _.reject issue.labels, (label) ->
label.title is board.title
getBoardsForIssue: (issue) ->
_.filter BoardsStore.state.boards, (board) ->
foundIssue = _.find board.issues, (boardIssue) ->
issue?.id == boardIssue?.id
foundIssue?
clearDone: ->
Vue.set(BoardsStore.state, 'done', {})
((w) => {
w.BoardsStore = {
state: {
boards: [],
done: {},
filters: {
author: {},
assignee: {},
milestone: {},
}
},
removeBoard: (id) => {
BoardsStore.state.boards = _.reject(BoardsStore.state.boards, (board) => {
return board.id === id;
});
},
moveBoard: (oldIndex, newIndex) => {
const boardFrom = _.find(BoardsStore.state.boards, (board) => {
return board.index === oldIndex;
});
service.updateBoard(boardFrom.id, newIndex);
const boardTo = _.find(BoardsStore.state.boards, (board) => {
return board.index === newIndex;
});
boardFrom.index = newIndex;
if (newIndex > boardTo.index) {
boardTo.index--;
} else {
boardTo.index++;
}
},
moveCardToBoard: (boardFromId, boardToId, issueId, toIndex) => {
const boardFrom = _.find(BoardsStore.state.boards, (board) => {
return board.id === boardFromId;
});
const boardTo = _.find(BoardsStore.state.boards, (board) => {
return board.id === boardToId;
});
let issue = _.find(boardFrom.issues, (issue) => {
return issue.id === issueId;
});
const issueTo = _.find(boardTo.issues, (issue) => {
return issue.id === issueId;
});
const issueBoards = BoardsStore.getBoardsForIssue(issue);
// Remove the issue from old board
boardFrom.issues = _.reject(boardFrom.issues, (issue) => {
return issue.id === issueId;
});
// Add to new boards issues if it doesn't already exist
if (issueTo !== null) {
issue = issueTo;
} else {
boardTo.issues.splice(toIndex, 0, issue);
}
if (boardTo.id === 'done' && boardFrom.id !== 'backlog') {
BoardsStore.removeIssueFromBoards(issue, issueBoards);
issue.labels = _.reject(issue.labels, (label) => {
return label.title === boardFrom.title;
});
} else {
if (boardTo.label !== null) {
BoardsStore.removeIssueFromBoard(issue, boardFrom);
foundLabel = _.find(issue.labels, (label) => {
return label.title === boardTo.title;
});
if (foundLabel === null) {
issue.labels.push(boardTo.label);
}
}
}
},
removeIssueFromBoards: (issue, boards) => {
const boardLabels = _.map(boards, (board) => {
return board.label.title;
});
boards.issues = _.each(boards, (board) => {
board.issues = _.reject(board.issues, (boardIssue) => {
return issue.id === boardIssue.id;
});
});
issue.labels = _.reject(issue.labels, (label) => {
return boardLabels.indexOf(label.title) !== -1;
});
},
removeIssueFromBoard: (issue, board) => {
issue.labels = _.reject(issue.labels, (label) => {
return label.title === board.title;
});
},
getBoardsForIssue: (issue) => {
_.filter(BoardsStore.state.boards, (board) => {
const foundIssue = _.find(board.issues, (boardIssue) => {
return issue.id === boardIssue.id;
});
return foundIssue !== null;
});
},
clearDone: () => {
Vue.set(BoardsStore.state, 'done', {});
}
};
}(window));
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