summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/boards
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/boards')
-rw-r--r--app/assets/javascripts/boards/boards_bundle.js.es613
-rw-r--r--app/assets/javascripts/boards/components/board.js.es621
-rw-r--r--app/assets/javascripts/boards/components/board_card.js.es634
-rw-r--r--app/assets/javascripts/boards/components/board_new_issue.js.es67
-rw-r--r--app/assets/javascripts/boards/components/board_sidebar.js.es652
-rw-r--r--app/assets/javascripts/boards/filters/due_date_filters.js.es64
-rw-r--r--app/assets/javascripts/boards/mixins/sortable_default_options.js.es62
-rw-r--r--app/assets/javascripts/boards/models/issue.js.es623
-rw-r--r--app/assets/javascripts/boards/models/milestone.js.es66
-rw-r--r--app/assets/javascripts/boards/services/board_service.js.es62
-rw-r--r--app/assets/javascripts/boards/stores/boards_store.js.es63
11 files changed, 161 insertions, 6 deletions
diff --git a/app/assets/javascripts/boards/boards_bundle.js.es6 b/app/assets/javascripts/boards/boards_bundle.js.es6
index d4f8f4b9420..56f91503017 100644
--- a/app/assets/javascripts/boards/boards_bundle.js.es6
+++ b/app/assets/javascripts/boards/boards_bundle.js.es6
@@ -5,7 +5,9 @@
//= require_tree ./stores
//= require_tree ./services
//= require_tree ./mixins
+//= require_tree ./filters
//= require ./components/board
+//= require ./components/board_sidebar
//= require ./components/new_list_dropdown
//= require ./vue_resource_interceptor
@@ -22,7 +24,8 @@ $(() => {
gl.IssueBoardsApp = new Vue({
el: $boardApp,
components: {
- 'board': gl.issueBoards.Board
+ 'board': gl.issueBoards.Board,
+ 'board-sidebar': gl.issueBoards.BoardSidebar
},
data: {
state: Store.state,
@@ -30,9 +33,15 @@ $(() => {
endpoint: $boardApp.dataset.endpoint,
boardId: $boardApp.dataset.boardId,
disabled: $boardApp.dataset.disabled === 'true',
- issueLinkBase: $boardApp.dataset.issueLinkBase
+ issueLinkBase: $boardApp.dataset.issueLinkBase,
+ detailIssue: Store.detail
},
init: Store.create.bind(Store),
+ computed: {
+ detailIssueVisible () {
+ return Object.keys(this.detailIssue.issue).length;
+ }
+ },
created () {
gl.boardService = new BoardService(this.endpoint, this.boardId);
},
diff --git a/app/assets/javascripts/boards/components/board.js.es6 b/app/assets/javascripts/boards/components/board.js.es6
index cacb36a897f..500213a3a43 100644
--- a/app/assets/javascripts/boards/components/board.js.es6
+++ b/app/assets/javascripts/boards/components/board.js.es6
@@ -21,6 +21,7 @@
},
data () {
return {
+ detailIssue: Store.detail,
filters: Store.state.filters,
showIssueForm: false
};
@@ -32,6 +33,26 @@
this.list.getIssues(true);
},
deep: true
+ },
+ detailIssue: {
+ handler () {
+ if (!Object.keys(this.detailIssue.issue).length) return;
+
+ const issue = this.list.findIssue(this.detailIssue.issue.id);
+
+ if (issue) {
+ const boardsList = document.querySelectorAll('.boards-list')[0];
+ const right = (this.$el.offsetLeft + this.$el.offsetWidth) - boardsList.offsetWidth;
+ const left = boardsList.scrollLeft - this.$el.offsetLeft;
+
+ if (right - boardsList.scrollLeft > 0) {
+ boardsList.scrollLeft = right;
+ } else if (left > 0) {
+ boardsList.scrollLeft = this.$el.offsetLeft;
+ }
+ }
+ },
+ deep: true
}
},
methods: {
diff --git a/app/assets/javascripts/boards/components/board_card.js.es6 b/app/assets/javascripts/boards/components/board_card.js.es6
index 4a7cfeaeab2..f743d72f936 100644
--- a/app/assets/javascripts/boards/components/board_card.js.es6
+++ b/app/assets/javascripts/boards/components/board_card.js.es6
@@ -12,6 +12,17 @@
disabled: Boolean,
index: Number
},
+ data () {
+ return {
+ showDetail: false,
+ detailIssue: Store.detail
+ };
+ },
+ computed: {
+ issueDetailVisible () {
+ return this.detailIssue.issue && this.detailIssue.issue.id === this.issue.id;
+ }
+ },
methods: {
filterByLabel (label, e) {
let labelToggleText = label.title;
@@ -37,6 +48,29 @@
$('.labels-filter .dropdown-toggle-text').text(labelToggleText);
Store.updateFiltersUrl();
+ },
+ mouseDown () {
+ this.showDetail = true;
+ },
+ mouseMove () {
+ if (this.showDetail) {
+ this.showDetail = false;
+ }
+ },
+ showIssue (e) {
+ const targetTagName = e.target.tagName.toLowerCase();
+
+ if (targetTagName === 'a' || targetTagName === 'button') return;
+
+ if (this.showDetail) {
+ this.showDetail = false;
+
+ if (Store.detail.issue && Store.detail.issue.id === this.issue.id) {
+ Store.detail.issue = {};
+ } else {
+ Store.detail.issue = this.issue;
+ }
+ }
}
}
});
diff --git a/app/assets/javascripts/boards/components/board_new_issue.js.es6 b/app/assets/javascripts/boards/components/board_new_issue.js.es6
index a4fad422eca..b31adfdb8da 100644
--- a/app/assets/javascripts/boards/components/board_new_issue.js.es6
+++ b/app/assets/javascripts/boards/components/board_new_issue.js.es6
@@ -1,4 +1,6 @@
(() => {
+ const Store = gl.issueBoards.BoardsStore;
+
window.gl = window.gl || {};
gl.issueBoards.BoardNewIssue = Vue.extend({
@@ -27,13 +29,16 @@
const labels = this.list.label ? [this.list.label] : [];
const issue = new ListIssue({
title: this.title,
- labels
+ labels,
+ subscribed: true
});
this.list.newIssue(issue)
.then((data) => {
// Need this because our jQuery very kindly disables buttons on ALL form submissions
$(this.$els.submitButton).enable();
+
+ Store.detail.issue = issue;
})
.catch(() => {
// Need this because our jQuery very kindly disables buttons on ALL form submissions
diff --git a/app/assets/javascripts/boards/components/board_sidebar.js.es6 b/app/assets/javascripts/boards/components/board_sidebar.js.es6
new file mode 100644
index 00000000000..e83e69247d9
--- /dev/null
+++ b/app/assets/javascripts/boards/components/board_sidebar.js.es6
@@ -0,0 +1,52 @@
+(() => {
+ const Store = gl.issueBoards.BoardsStore;
+
+ window.gl = window.gl || {};
+ window.gl.issueBoards = window.gl.issueBoards || {};
+
+ gl.issueBoards.BoardSidebar = Vue.extend({
+ props: {
+ currentUser: Object
+ },
+ data() {
+ return {
+ detail: Store.detail,
+ issue: {}
+ };
+ },
+ computed: {
+ showSidebar () {
+ return Object.keys(this.issue).length;
+ }
+ },
+ watch: {
+ detail: {
+ handler () {
+ this.issue = this.detail.issue;
+ },
+ deep: true
+ },
+ issue () {
+ if (this.showSidebar) {
+ this.$nextTick(() => {
+ $('.right-sidebar').getNiceScroll(0).doScrollTop(0, 0);
+ $('.right-sidebar').getNiceScroll().resize();
+ });
+ }
+ }
+ },
+ methods: {
+ closeSidebar () {
+ this.detail.issue = {};
+ }
+ },
+ ready () {
+ new IssuableContext(this.currentUser);
+ new MilestoneSelect();
+ new gl.DueDateSelectors();
+ new LabelsSelect();
+ new Sidebar();
+ new Subscription('.subscription');
+ }
+ });
+})();
diff --git a/app/assets/javascripts/boards/filters/due_date_filters.js.es6 b/app/assets/javascripts/boards/filters/due_date_filters.js.es6
new file mode 100644
index 00000000000..50ef1911022
--- /dev/null
+++ b/app/assets/javascripts/boards/filters/due_date_filters.js.es6
@@ -0,0 +1,4 @@
+Vue.filter('due-date', (value) => {
+ const date = new Date(value);
+ return $.datepicker.formatDate('M d, yy', date);
+});
diff --git a/app/assets/javascripts/boards/mixins/sortable_default_options.js.es6 b/app/assets/javascripts/boards/mixins/sortable_default_options.js.es6
index f629d45c587..bd9ba7d5118 100644
--- a/app/assets/javascripts/boards/mixins/sortable_default_options.js.es6
+++ b/app/assets/javascripts/boards/mixins/sortable_default_options.js.es6
@@ -22,7 +22,7 @@
fallbackOnBody: true,
ghostClass: 'is-ghost',
filter: '.has-tooltip, .btn',
- delay: gl.issueBoards.touchEnabled ? 100 : 0,
+ delay: gl.issueBoards.touchEnabled ? 100 : 50,
scrollSensitivity: gl.issueBoards.touchEnabled ? 60 : 100,
scrollSpeed: 20,
onStart: gl.issueBoards.onStart,
diff --git a/app/assets/javascripts/boards/models/issue.js.es6 b/app/assets/javascripts/boards/models/issue.js.es6
index eb082103de9..03fd6c05d87 100644
--- a/app/assets/javascripts/boards/models/issue.js.es6
+++ b/app/assets/javascripts/boards/models/issue.js.es6
@@ -3,12 +3,18 @@ class ListIssue {
this.id = obj.iid;
this.title = obj.title;
this.confidential = obj.confidential;
+ this.dueDate = obj.due_date;
+ this.subscribed = obj.subscribed;
this.labels = [];
if (obj.assignee) {
this.assignee = new ListUser(obj.assignee);
}
+ if (obj.milestone) {
+ this.milestone = new ListMilestone(obj.milestone);
+ }
+
obj.labels.forEach((label) => {
this.labels.push(new ListLabel(label));
});
@@ -41,4 +47,21 @@ class ListIssue {
getLists () {
return gl.issueBoards.BoardsStore.state.lists.filter( list => list.findIssue(this.id) );
}
+
+ update (url) {
+ const data = {
+ issue: {
+ milestone_id: this.milestone ? this.milestone.id : null,
+ due_date: this.dueDate,
+ assignee_id: this.assignee ? this.assignee.id : null,
+ label_ids: this.labels.map( (label) => label.id )
+ }
+ };
+
+ if (!data.issue.label_ids.length) {
+ data.issue.label_ids = [''];
+ }
+
+ return Vue.http.patch(url, data);
+ }
}
diff --git a/app/assets/javascripts/boards/models/milestone.js.es6 b/app/assets/javascripts/boards/models/milestone.js.es6
new file mode 100644
index 00000000000..577adf11265
--- /dev/null
+++ b/app/assets/javascripts/boards/models/milestone.js.es6
@@ -0,0 +1,6 @@
+class ListMilestone {
+ constructor (obj) {
+ this.id = obj.id;
+ this.title = obj.title;
+ }
+}
diff --git a/app/assets/javascripts/boards/services/board_service.js.es6 b/app/assets/javascripts/boards/services/board_service.js.es6
index b9c91cbf31e..b76063911bb 100644
--- a/app/assets/javascripts/boards/services/board_service.js.es6
+++ b/app/assets/javascripts/boards/services/board_service.js.es6
@@ -1,7 +1,5 @@
class BoardService {
constructor (root, boardId) {
- Vue.http.options.root = root;
-
this.lists = Vue.resource(`${root}/${boardId}/lists{/id}`, {}, {
generate: {
method: 'POST',
diff --git a/app/assets/javascripts/boards/stores/boards_store.js.es6 b/app/assets/javascripts/boards/stores/boards_store.js.es6
index a12d3a59265..c30f66e3a5a 100644
--- a/app/assets/javascripts/boards/stores/boards_store.js.es6
+++ b/app/assets/javascripts/boards/stores/boards_store.js.es6
@@ -5,6 +5,9 @@
gl.issueBoards.BoardsStore = {
disabled: false,
state: {},
+ detail: {
+ issue: {}
+ },
moving: {
issue: {},
list: {}