Merge branch 'vue2' into 'master'
Migration to Vuejs version 2 List of required changes for our Vue usages - `init` ➡️ `beforeCreate` - `read` ➡️ `mounted` - `$els` ➡️ `$refs` - 🚫 `$remove` completely removed. ✅ Use `indexOf` and `splice` - 🚫 HTML embedding with `{{{ }}}` is deprecated. ✅ Use `v-html` See merge request !7254
This commit is contained in:
commit
52f29501be
41 changed files with 7661 additions and 10220 deletions
|
@ -22,6 +22,8 @@ $(() => {
|
||||||
gl.IssueBoardsApp.$destroy(true);
|
gl.IssueBoardsApp.$destroy(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Store.create();
|
||||||
|
|
||||||
gl.IssueBoardsApp = new Vue({
|
gl.IssueBoardsApp = new Vue({
|
||||||
el: $boardApp,
|
el: $boardApp,
|
||||||
components: {
|
components: {
|
||||||
|
@ -37,16 +39,15 @@ $(() => {
|
||||||
issueLinkBase: $boardApp.dataset.issueLinkBase,
|
issueLinkBase: $boardApp.dataset.issueLinkBase,
|
||||||
detailIssue: Store.detail
|
detailIssue: Store.detail
|
||||||
},
|
},
|
||||||
init: Store.create.bind(Store),
|
|
||||||
computed: {
|
computed: {
|
||||||
detailIssueVisible () {
|
detailIssueVisible () {
|
||||||
return Object.keys(this.detailIssue.issue).length;
|
return Object.keys(this.detailIssue.issue).length;
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
created () {
|
created () {
|
||||||
gl.boardService = new BoardService(this.endpoint, this.boardId);
|
gl.boardService = new BoardService(this.endpoint, this.boardId);
|
||||||
},
|
},
|
||||||
ready () {
|
mounted () {
|
||||||
Store.disabled = this.disabled;
|
Store.disabled = this.disabled;
|
||||||
gl.boardService.all()
|
gl.boardService.all()
|
||||||
.then((resp) => {
|
.then((resp) => {
|
||||||
|
@ -60,6 +61,8 @@ $(() => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.state.lists = _.sortBy(this.state.lists, 'position');
|
||||||
|
|
||||||
Store.addBlankState();
|
Store.addBlankState();
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
});
|
});
|
||||||
|
@ -70,6 +73,9 @@ $(() => {
|
||||||
el: '#js-boards-seach',
|
el: '#js-boards-seach',
|
||||||
data: {
|
data: {
|
||||||
filters: Store.state.filters
|
filters: Store.state.filters
|
||||||
|
},
|
||||||
|
mounted () {
|
||||||
|
gl.issueBoards.newListDropdownInit();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
window.gl.issueBoards = window.gl.issueBoards || {};
|
window.gl.issueBoards = window.gl.issueBoards || {};
|
||||||
|
|
||||||
gl.issueBoards.Board = Vue.extend({
|
gl.issueBoards.Board = Vue.extend({
|
||||||
|
template: '#js-board-template',
|
||||||
components: {
|
components: {
|
||||||
'board-list': gl.issueBoards.BoardList,
|
'board-list': gl.issueBoards.BoardList,
|
||||||
'board-delete': gl.issueBoards.BoardDelete,
|
'board-delete': gl.issueBoards.BoardDelete,
|
||||||
|
@ -24,7 +25,6 @@
|
||||||
return {
|
return {
|
||||||
detailIssue: Store.detail,
|
detailIssue: Store.detail,
|
||||||
filters: Store.state.filters,
|
filters: Store.state.filters,
|
||||||
showIssueForm: false
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
@ -58,10 +58,10 @@
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
showNewIssueForm() {
|
showNewIssueForm() {
|
||||||
this.showIssueForm = !this.showIssueForm;
|
this.$refs['board-list'].showIssueForm = !this.$refs['board-list'].showIssueForm;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ready () {
|
mounted () {
|
||||||
const options = gl.issueBoards.getBoardSortableDefaultOptions({
|
const options = gl.issueBoards.getBoardSortableDefaultOptions({
|
||||||
disabled: this.disabled,
|
disabled: this.disabled,
|
||||||
group: 'boards',
|
group: 'boards',
|
||||||
|
@ -72,13 +72,9 @@
|
||||||
|
|
||||||
if (e.newIndex !== undefined && e.oldIndex !== e.newIndex) {
|
if (e.newIndex !== undefined && e.oldIndex !== e.newIndex) {
|
||||||
const order = this.sortable.toArray(),
|
const order = this.sortable.toArray(),
|
||||||
$board = this.$parent.$refs.board[e.oldIndex + 1],
|
list = Store.findList('id', parseInt(e.item.dataset.id));
|
||||||
list = $board.list;
|
|
||||||
|
|
||||||
$board.$destroy(true);
|
|
||||||
|
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
Store.state.lists.splice(e.newIndex, 0, list);
|
|
||||||
Store.moveList(list, order);
|
Store.moveList(list, order);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -87,8 +83,5 @@
|
||||||
|
|
||||||
this.sortable = Sortable.create(this.$el.parentNode, options);
|
this.sortable = Sortable.create(this.$el.parentNode, options);
|
||||||
},
|
},
|
||||||
beforeDestroy () {
|
|
||||||
Store.state.lists.$remove(this.list);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -30,6 +30,8 @@
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Store.state.lists = _.sortBy(Store.state.lists, 'position');
|
||||||
|
|
||||||
// Save the labels
|
// Save the labels
|
||||||
gl.boardService.generateDefaultLists()
|
gl.boardService.generateDefaultLists()
|
||||||
.then((resp) => {
|
.then((resp) => {
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
window.gl.issueBoards = window.gl.issueBoards || {};
|
window.gl.issueBoards = window.gl.issueBoards || {};
|
||||||
|
|
||||||
gl.issueBoards.BoardCard = Vue.extend({
|
gl.issueBoards.BoardCard = Vue.extend({
|
||||||
|
template: '#js-board-list-card',
|
||||||
props: {
|
props: {
|
||||||
list: Object,
|
list: Object,
|
||||||
issue: Object,
|
issue: Object,
|
||||||
|
@ -53,11 +54,6 @@
|
||||||
mouseDown () {
|
mouseDown () {
|
||||||
this.showDetail = true;
|
this.showDetail = true;
|
||||||
},
|
},
|
||||||
mouseMove () {
|
|
||||||
if (this.showDetail) {
|
|
||||||
this.showDetail = false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
showIssue (e) {
|
showIssue (e) {
|
||||||
const targetTagName = e.target.tagName.toLowerCase();
|
const targetTagName = e.target.tagName.toLowerCase();
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
window.gl.issueBoards = window.gl.issueBoards || {};
|
window.gl.issueBoards = window.gl.issueBoards || {};
|
||||||
|
|
||||||
gl.issueBoards.BoardList = Vue.extend({
|
gl.issueBoards.BoardList = Vue.extend({
|
||||||
|
template: '#js-board-list-template',
|
||||||
components: {
|
components: {
|
||||||
'board-card': gl.issueBoards.BoardCard,
|
'board-card': gl.issueBoards.BoardCard,
|
||||||
'board-new-issue': gl.issueBoards.BoardNewIssue
|
'board-new-issue': gl.issueBoards.BoardNewIssue
|
||||||
|
@ -19,20 +20,20 @@
|
||||||
issues: Array,
|
issues: Array,
|
||||||
loading: Boolean,
|
loading: Boolean,
|
||||||
issueLinkBase: String,
|
issueLinkBase: String,
|
||||||
showIssueForm: Boolean
|
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
scrollOffset: 250,
|
scrollOffset: 250,
|
||||||
filters: Store.state.filters,
|
filters: Store.state.filters,
|
||||||
showCount: false
|
showCount: false,
|
||||||
|
showIssueForm: false
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
filters: {
|
filters: {
|
||||||
handler () {
|
handler () {
|
||||||
this.list.loadingMore = false;
|
this.list.loadingMore = false;
|
||||||
this.$els.list.scrollTop = 0;
|
this.$refs.list.scrollTop = 0;
|
||||||
},
|
},
|
||||||
deep: true
|
deep: true
|
||||||
},
|
},
|
||||||
|
@ -51,15 +52,20 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
orderedIssues () {
|
||||||
|
return _.sortBy(this.issues, 'priority');
|
||||||
|
},
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
listHeight () {
|
listHeight () {
|
||||||
return this.$els.list.getBoundingClientRect().height;
|
return this.$refs.list.getBoundingClientRect().height;
|
||||||
},
|
},
|
||||||
scrollHeight () {
|
scrollHeight () {
|
||||||
return this.$els.list.scrollHeight;
|
return this.$refs.list.scrollHeight;
|
||||||
},
|
},
|
||||||
scrollTop () {
|
scrollTop () {
|
||||||
return this.$els.list.scrollTop + this.listHeight();
|
return this.$refs.list.scrollTop + this.listHeight();
|
||||||
},
|
},
|
||||||
loadNextPage () {
|
loadNextPage () {
|
||||||
const getIssues = this.list.nextPage();
|
const getIssues = this.list.nextPage();
|
||||||
|
@ -72,7 +78,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ready () {
|
mounted () {
|
||||||
const options = gl.issueBoards.getBoardSortableDefaultOptions({
|
const options = gl.issueBoards.getBoardSortableDefaultOptions({
|
||||||
group: 'issues',
|
group: 'issues',
|
||||||
sort: false,
|
sort: false,
|
||||||
|
@ -81,23 +87,27 @@
|
||||||
onStart: (e) => {
|
onStart: (e) => {
|
||||||
const card = this.$refs.issue[e.oldIndex];
|
const card = this.$refs.issue[e.oldIndex];
|
||||||
|
|
||||||
|
card.showDetail = false;
|
||||||
Store.moving.issue = card.issue;
|
Store.moving.issue = card.issue;
|
||||||
Store.moving.list = card.list;
|
Store.moving.list = card.list;
|
||||||
|
|
||||||
gl.issueBoards.onStart();
|
gl.issueBoards.onStart();
|
||||||
},
|
},
|
||||||
onAdd: (e) => {
|
onAdd: (e) => {
|
||||||
gl.issueBoards.BoardsStore.moveIssueToList(Store.moving.list, this.list, Store.moving.issue);
|
// Add the element back to original list to allow Vue to handle DOM updates
|
||||||
|
e.from.appendChild(e.item);
|
||||||
|
|
||||||
|
this.$nextTick(() => {
|
||||||
|
// Update the issues once we know the element has been moved
|
||||||
|
gl.issueBoards.BoardsStore.moveIssueToList(Store.moving.list, this.list, Store.moving.issue);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
onRemove: (e) => {
|
|
||||||
this.$refs.issue[e.oldIndex].$destroy(true);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this.sortable = Sortable.create(this.$els.list, options);
|
this.sortable = Sortable.create(this.$refs.list, options);
|
||||||
|
|
||||||
// Scroll event on list to load more
|
// Scroll event on list to load more
|
||||||
this.$els.list.onscroll = () => {
|
this.$refs.list.onscroll = () => {
|
||||||
if ((this.scrollTop() > this.scrollHeight() - this.scrollOffset) && !this.list.loadingMore) {
|
if ((this.scrollTop() > this.scrollHeight() - this.scrollOffset) && !this.list.loadingMore) {
|
||||||
this.loadNextPage();
|
this.loadNextPage();
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
gl.issueBoards.BoardNewIssue = Vue.extend({
|
gl.issueBoards.BoardNewIssue = Vue.extend({
|
||||||
props: {
|
props: {
|
||||||
list: Object,
|
list: Object,
|
||||||
showIssueForm: Boolean
|
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -15,11 +14,6 @@
|
||||||
error: false
|
error: false
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
watch: {
|
|
||||||
showIssueForm () {
|
|
||||||
this.$els.input.focus();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
submit(e) {
|
submit(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
@ -37,28 +31,30 @@
|
||||||
this.list.newIssue(issue)
|
this.list.newIssue(issue)
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
// Need this because our jQuery very kindly disables buttons on ALL form submissions
|
// Need this because our jQuery very kindly disables buttons on ALL form submissions
|
||||||
$(this.$els.submitButton).enable();
|
$(this.$refs.submitButton).enable();
|
||||||
|
|
||||||
Store.detail.issue = issue;
|
Store.detail.issue = issue;
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
// Need this because our jQuery very kindly disables buttons on ALL form submissions
|
// Need this because our jQuery very kindly disables buttons on ALL form submissions
|
||||||
$(this.$els.submitButton).enable();
|
$(this.$refs.submitButton).enable();
|
||||||
|
|
||||||
// Remove the issue
|
// Remove the issue
|
||||||
this.list.removeIssue(issue);
|
this.list.removeIssue(issue);
|
||||||
|
|
||||||
// Show error message
|
// Show error message
|
||||||
this.error = true;
|
this.error = true;
|
||||||
this.showIssueForm = true;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this.cancel();
|
this.cancel();
|
||||||
},
|
},
|
||||||
cancel() {
|
cancel() {
|
||||||
this.showIssueForm = false;
|
|
||||||
this.title = '';
|
this.title = '';
|
||||||
|
this.$parent.showIssueForm = false;
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
mounted() {
|
||||||
|
this.$refs.input.focus();
|
||||||
|
},
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
this.detail.issue = {};
|
this.detail.issue = {};
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ready () {
|
mounted () {
|
||||||
new IssuableContext(this.currentUser);
|
new IssuableContext(this.currentUser);
|
||||||
new MilestoneSelect();
|
new MilestoneSelect();
|
||||||
new gl.DueDateSelectors();
|
new gl.DueDateSelectors();
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
$(() => {
|
(() => {
|
||||||
|
window.gl = window.gl || {};
|
||||||
|
window.gl.issueBoards = window.gl.issueBoards || {};
|
||||||
|
|
||||||
const Store = gl.issueBoards.BoardsStore;
|
const Store = gl.issueBoards.BoardsStore;
|
||||||
|
|
||||||
$(document).off('created.label').on('created.label', (e, label) => {
|
$(document).off('created.label').on('created.label', (e, label) => {
|
||||||
|
@ -15,54 +18,58 @@ $(() => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
$('.js-new-board-list').each(function () {
|
gl.issueBoards.newListDropdownInit = () => {
|
||||||
const $this = $(this);
|
$('.js-new-board-list').each(function () {
|
||||||
new gl.CreateLabelDropdown($this.closest('.dropdown').find('.dropdown-new-label'), $this.data('namespace-path'), $this.data('project-path'));
|
const $this = $(this);
|
||||||
|
new gl.CreateLabelDropdown($this.closest('.dropdown').find('.dropdown-new-label'), $this.data('namespace-path'), $this.data('project-path'));
|
||||||
|
|
||||||
$this.glDropdown({
|
$this.glDropdown({
|
||||||
data(term, callback) {
|
data(term, callback) {
|
||||||
$.get($this.attr('data-labels'))
|
$.get($this.attr('data-labels'))
|
||||||
.then((resp) => {
|
.then((resp) => {
|
||||||
callback(resp);
|
callback(resp);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
renderRow (label) {
|
renderRow (label) {
|
||||||
const active = Store.findList('title', label.title),
|
const active = Store.findList('title', label.title),
|
||||||
$li = $('<li />'),
|
$li = $('<li />'),
|
||||||
$a = $('<a />', {
|
$a = $('<a />', {
|
||||||
class: (active ? `is-active js-board-list-${active.id}` : ''),
|
class: (active ? `is-active js-board-list-${active.id}` : ''),
|
||||||
text: label.title,
|
text: label.title,
|
||||||
href: '#'
|
href: '#'
|
||||||
}),
|
}),
|
||||||
$labelColor = $('<span />', {
|
$labelColor = $('<span />', {
|
||||||
class: 'dropdown-label-box',
|
class: 'dropdown-label-box',
|
||||||
style: `background-color: ${label.color}`
|
style: `background-color: ${label.color}`
|
||||||
});
|
});
|
||||||
|
|
||||||
return $li.append($a.prepend($labelColor));
|
return $li.append($a.prepend($labelColor));
|
||||||
},
|
},
|
||||||
search: {
|
search: {
|
||||||
fields: ['title']
|
fields: ['title']
|
||||||
},
|
},
|
||||||
filterable: true,
|
filterable: true,
|
||||||
selectable: true,
|
selectable: true,
|
||||||
multiSelect: true,
|
multiSelect: true,
|
||||||
clicked (label, $el, e) {
|
clicked (label, $el, e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
if (!Store.findList('title', label.title)) {
|
if (!Store.findList('title', label.title)) {
|
||||||
Store.new({
|
Store.new({
|
||||||
title: label.title,
|
|
||||||
position: Store.state.lists.length - 2,
|
|
||||||
list_type: 'label',
|
|
||||||
label: {
|
|
||||||
id: label.id,
|
|
||||||
title: label.title,
|
title: label.title,
|
||||||
color: label.color
|
position: Store.state.lists.length - 2,
|
||||||
}
|
list_type: 'label',
|
||||||
});
|
label: {
|
||||||
|
id: label.id,
|
||||||
|
title: label.title,
|
||||||
|
color: label.color
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Store.state.lists = _.sortBy(Store.state.lists, 'position');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
});
|
});
|
||||||
});
|
};
|
||||||
});
|
})();
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
fallbackOnBody: true,
|
fallbackOnBody: true,
|
||||||
ghostClass: 'is-ghost',
|
ghostClass: 'is-ghost',
|
||||||
filter: '.board-delete, .btn',
|
filter: '.board-delete, .btn',
|
||||||
delay: gl.issueBoards.touchEnabled ? 100 : 50,
|
delay: gl.issueBoards.touchEnabled ? 100 : 0,
|
||||||
scrollSensitivity: gl.issueBoards.touchEnabled ? 60 : 100,
|
scrollSensitivity: gl.issueBoards.touchEnabled ? 60 : 100,
|
||||||
scrollSpeed: 20,
|
scrollSpeed: 20,
|
||||||
onStart: gl.issueBoards.onStart,
|
onStart: gl.issueBoards.onStart,
|
||||||
|
|
|
@ -42,7 +42,8 @@ class List {
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy () {
|
destroy () {
|
||||||
gl.issueBoards.BoardsStore.state.lists.$remove(this);
|
const index = gl.issueBoards.BoardsStore.state.lists.indexOf(this);
|
||||||
|
gl.issueBoards.BoardsStore.state.lists.splice(index, 1);
|
||||||
gl.issueBoards.BoardsStore.updateNewListDropdown(this.id);
|
gl.issueBoards.BoardsStore.updateNewListDropdown(this.id);
|
||||||
|
|
||||||
gl.boardService.destroyList(this.id);
|
gl.boardService.destroyList(this.id);
|
||||||
|
|
|
@ -39,6 +39,8 @@
|
||||||
// Remove any new issues from the backlog
|
// Remove any new issues from the backlog
|
||||||
// as they will be visible in the new list
|
// as they will be visible in the new list
|
||||||
list.issues.forEach(backlogList.removeIssue.bind(backlogList));
|
list.issues.forEach(backlogList.removeIssue.bind(backlogList));
|
||||||
|
|
||||||
|
this.state.lists = _.sortBy(this.state.lists, 'position');
|
||||||
});
|
});
|
||||||
this.removeBlankState();
|
this.removeBlankState();
|
||||||
},
|
},
|
||||||
|
@ -58,6 +60,8 @@
|
||||||
title: 'Welcome to your Issue Board!',
|
title: 'Welcome to your Issue Board!',
|
||||||
position: 0
|
position: 0
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.state.lists = _.sortBy(this.state.lists, 'position');
|
||||||
},
|
},
|
||||||
removeBlankState () {
|
removeBlankState () {
|
||||||
this.removeList('blank');
|
this.removeList('blank');
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
((w) => {
|
(() => {
|
||||||
w.CommentAndResolveBtn = Vue.extend({
|
const CommentAndResolveBtn = Vue.extend({
|
||||||
props: {
|
props: {
|
||||||
discussionId: String,
|
discussionId: String,
|
||||||
textareaIsEmpty: Boolean
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
textareaIsEmpty: true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
discussion: function () {
|
discussion: function () {
|
||||||
|
@ -35,7 +39,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ready: function () {
|
mounted: function () {
|
||||||
const $textarea = $(`#new-discussion-note-form-${this.discussionId} .note-textarea`);
|
const $textarea = $(`#new-discussion-note-form-${this.discussionId} .note-textarea`);
|
||||||
this.textareaIsEmpty = $textarea.val() === '';
|
this.textareaIsEmpty = $textarea.val() === '';
|
||||||
|
|
||||||
|
@ -47,4 +51,6 @@
|
||||||
$(`#new-discussion-note-form-${this.discussionId} .note-textarea`).off('input.comment-and-resolve-btn');
|
$(`#new-discussion-note-form-${this.discussionId} .note-textarea`).off('input.comment-and-resolve-btn');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Vue.component('comment-and-resolve-btn', CommentAndResolveBtn);
|
||||||
})(window);
|
})(window);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
((w) => {
|
(() => {
|
||||||
w.ResolveBtn = Vue.extend({
|
const ResolveBtn = Vue.extend({
|
||||||
props: {
|
props: {
|
||||||
noteId: Number,
|
noteId: Number,
|
||||||
discussionId: String,
|
discussionId: String,
|
||||||
|
@ -54,7 +54,7 @@
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
updateTooltip: function () {
|
updateTooltip: function () {
|
||||||
$(this.$els.button)
|
$(this.$refs.button)
|
||||||
.tooltip('hide')
|
.tooltip('hide')
|
||||||
.tooltip('fixTitle');
|
.tooltip('fixTitle');
|
||||||
},
|
},
|
||||||
|
@ -89,8 +89,8 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
compiled: function () {
|
mounted: function () {
|
||||||
$(this.$els.button).tooltip({
|
$(this.$refs.button).tooltip({
|
||||||
container: 'body'
|
container: 'body'
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -101,4 +101,6 @@
|
||||||
CommentsStore.create(this.discussionId, this.noteId, this.canResolve, this.resolved, this.resolvedBy);
|
CommentsStore.create(this.discussionId, this.noteId, this.canResolve, this.resolved, this.resolvedBy);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})(window);
|
|
||||||
|
Vue.component('resolve-btn', ResolveBtn);
|
||||||
|
})();
|
||||||
|
|
|
@ -13,6 +13,9 @@
|
||||||
computed: {
|
computed: {
|
||||||
allResolved: function () {
|
allResolved: function () {
|
||||||
return this.resolvedDiscussionCount === this.discussionCount;
|
return this.resolvedDiscussionCount === this.discussionCount;
|
||||||
|
},
|
||||||
|
resolvedCountText() {
|
||||||
|
return this.discussionCount === 1 ? 'discussion' : 'discussions';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
((w) => {
|
(() => {
|
||||||
w.ResolveDiscussionBtn = Vue.extend({
|
const ResolveDiscussionBtn = Vue.extend({
|
||||||
props: {
|
props: {
|
||||||
discussionId: String,
|
discussionId: String,
|
||||||
mergeRequestId: Number,
|
mergeRequestId: Number,
|
||||||
|
@ -54,4 +54,6 @@
|
||||||
CommentsStore.createDiscussion(this.discussionId, this.canResolve);
|
CommentsStore.createDiscussion(this.discussionId, this.canResolve);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})(window);
|
|
||||||
|
Vue.component('resolve-discussion-btn', ResolveDiscussionBtn);
|
||||||
|
})();
|
||||||
|
|
|
@ -8,24 +8,35 @@
|
||||||
//= require_directory ./components
|
//= require_directory ./components
|
||||||
|
|
||||||
$(() => {
|
$(() => {
|
||||||
window.DiffNotesApp = new Vue({
|
const COMPONENT_SELECTOR = 'resolve-btn, resolve-discussion-btn, jump-to-discussion, comment-and-resolve-btn';
|
||||||
el: '#diff-notes-app',
|
|
||||||
components: {
|
window.gl = window.gl || {};
|
||||||
'resolve-btn': ResolveBtn,
|
window.gl.diffNoteApps = {};
|
||||||
'resolve-discussion-btn': ResolveDiscussionBtn,
|
|
||||||
'comment-and-resolve-btn': CommentAndResolveBtn
|
gl.diffNotesCompileComponents = () => {
|
||||||
},
|
const $components = $(COMPONENT_SELECTOR).filter(function () {
|
||||||
methods: {
|
return $(this).closest('resolve-count').length !== 1;
|
||||||
compileComponents: function () {
|
});
|
||||||
const $components = $('resolve-btn, resolve-discussion-btn, jump-to-discussion');
|
|
||||||
if ($components.length) {
|
if ($components) {
|
||||||
$components.each(function () {
|
$components.each(function () {
|
||||||
DiffNotesApp.$compile($(this).get(0));
|
const $this = $(this);
|
||||||
});
|
const noteId = $this.attr(':note-id');
|
||||||
|
const tmp = Vue.extend({
|
||||||
|
template: $this.get(0).outerHTML
|
||||||
|
});
|
||||||
|
const tmpApp = new tmp().$mount();
|
||||||
|
|
||||||
|
if (noteId) {
|
||||||
|
gl.diffNoteApps[`note_${noteId}`] = tmpApp;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
$this.replaceWith(tmpApp.$el);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
|
||||||
|
gl.diffNotesCompileComponents();
|
||||||
|
|
||||||
new Vue({
|
new Vue({
|
||||||
el: '#resolve-count-app',
|
el: '#resolve-count-app',
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
this.loadEditor();
|
this.loadEditor();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ready() {
|
mounted() {
|
||||||
if (this.file.loadEditor) {
|
if (this.file.loadEditor) {
|
||||||
this.loadEditor();
|
this.loadEditor();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
/* eslint-disable */
|
|
||||||
((global) => {
|
|
||||||
|
|
||||||
global.mergeConflicts = global.mergeConflicts || {};
|
|
||||||
|
|
||||||
global.mergeConflicts.parallelConflictLine = Vue.extend({
|
|
||||||
props: {
|
|
||||||
file: Object,
|
|
||||||
line: Object
|
|
||||||
},
|
|
||||||
mixins: [global.mergeConflicts.utils, global.mergeConflicts.actions],
|
|
||||||
template: '#parallel-conflict-line'
|
|
||||||
});
|
|
||||||
|
|
||||||
})(window.gl || (window.gl = {}));
|
|
|
@ -7,10 +7,22 @@
|
||||||
props: {
|
props: {
|
||||||
file: Object
|
file: Object
|
||||||
},
|
},
|
||||||
mixins: [global.mergeConflicts.utils],
|
mixins: [global.mergeConflicts.utils, global.mergeConflicts.actions],
|
||||||
components: {
|
template: `
|
||||||
'parallel-conflict-line': gl.mergeConflicts.parallelConflictLine
|
<table>
|
||||||
}
|
<tr class="line_holder parallel" v-for="section in file.parallelLines">
|
||||||
|
<template v-for="line in section">
|
||||||
|
<td class="diff-line-num header" :class="lineCssClass(line)" v-if="line.isHeader"></td>
|
||||||
|
<td class="line_content header" :class="lineCssClass(line)" v-if="line.isHeader">
|
||||||
|
<strong>{{line.richText}}</strong>
|
||||||
|
<button class="btn" @click="handleSelected(file, line.id, line.section)">{{line.buttonTitle}}</button>
|
||||||
|
</td>
|
||||||
|
<td class="diff-line-num old_line" :class="lineCssClass(line)" v-if="!line.isHeader">{{line.lineNumber}}</td>
|
||||||
|
<td class="line_content parallel" :class="lineCssClass(line)" v-if="!line.isHeader" v-html="line.richText"></td>
|
||||||
|
</template>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
`,
|
||||||
});
|
});
|
||||||
|
|
||||||
})(window.gl || (window.gl = {}));
|
})(window.gl || (window.gl = {}));
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
//= require ./mixins/line_conflict_actions
|
//= require ./mixins/line_conflict_actions
|
||||||
//= require ./components/diff_file_editor
|
//= require ./components/diff_file_editor
|
||||||
//= require ./components/inline_conflict_lines
|
//= require ./components/inline_conflict_lines
|
||||||
//= require ./components/parallel_conflict_line
|
|
||||||
//= require ./components/parallel_conflict_lines
|
//= require ./components/parallel_conflict_lines
|
||||||
|
|
||||||
$(() => {
|
$(() => {
|
||||||
|
@ -49,7 +48,7 @@ $(() => {
|
||||||
mergeConflictsStore.setLoadingState(false);
|
mergeConflictsStore.setLoadingState(false);
|
||||||
|
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
$(conflictsEl.querySelectorAll('.js-syntax-highlight')).syntaxHighlight();
|
$('.js-syntax-highlight').syntaxHighlight();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
|
@ -227,8 +227,8 @@
|
||||||
return function(data) {
|
return function(data) {
|
||||||
$('#diffs').html(data.html);
|
$('#diffs').html(data.html);
|
||||||
|
|
||||||
if (typeof DiffNotesApp !== 'undefined') {
|
if (typeof gl.diffNotesCompileComponents !== 'undefined') {
|
||||||
DiffNotesApp.compileComponents();
|
gl.diffNotesCompileComponents();
|
||||||
}
|
}
|
||||||
|
|
||||||
gl.utils.localTimeAgo($('.js-timeago', 'div#diffs'));
|
gl.utils.localTimeAgo($('.js-timeago', 'div#diffs'));
|
||||||
|
|
|
@ -325,8 +325,8 @@
|
||||||
discussionContainer.append(note_html);
|
discussionContainer.append(note_html);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof DiffNotesApp !== 'undefined') {
|
if (typeof gl.diffNotesCompileComponents !== 'undefined') {
|
||||||
DiffNotesApp.compileComponents();
|
gl.diffNotesCompileComponents();
|
||||||
}
|
}
|
||||||
|
|
||||||
gl.utils.localTimeAgo($('.js-timeago', note_html), false);
|
gl.utils.localTimeAgo($('.js-timeago', note_html), false);
|
||||||
|
@ -466,8 +466,8 @@
|
||||||
|
|
||||||
$note_li.replaceWith($html);
|
$note_li.replaceWith($html);
|
||||||
|
|
||||||
if (typeof DiffNotesApp !== 'undefined') {
|
if (typeof gl.diffNotesCompileComponents !== 'undefined') {
|
||||||
DiffNotesApp.compileComponents();
|
gl.diffNotesCompileComponents();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -559,11 +559,9 @@
|
||||||
note = $(el);
|
note = $(el);
|
||||||
notes = note.closest(".notes");
|
notes = note.closest(".notes");
|
||||||
|
|
||||||
if (typeof DiffNotesApp !== "undefined" && DiffNotesApp !== null) {
|
if (typeof gl.diffNotesCompileComponents !== 'undefined') {
|
||||||
ref = DiffNotesApp.$refs[noteId];
|
if (gl.diffNoteApps[noteId]) {
|
||||||
|
gl.diffNoteApps[noteId].$destroy();
|
||||||
if (ref) {
|
|
||||||
ref.$destroy(true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -643,11 +641,12 @@
|
||||||
form.find('.js-note-target-close').remove();
|
form.find('.js-note-target-close').remove();
|
||||||
this.setupNoteForm(form);
|
this.setupNoteForm(form);
|
||||||
|
|
||||||
if (typeof DiffNotesApp !== 'undefined') {
|
if (typeof gl.diffNotesCompileComponents !== 'undefined') {
|
||||||
var $commentBtn = form.find('comment-and-resolve-btn');
|
var $commentBtn = form.find('comment-and-resolve-btn');
|
||||||
$commentBtn
|
$commentBtn
|
||||||
.attr(':discussion-id', "'" + dataHolder.data('discussionId') + "'");
|
.attr(':discussion-id', "'" + dataHolder.data('discussionId') + "'");
|
||||||
DiffNotesApp.$compile($commentBtn.get(0));
|
|
||||||
|
gl.diffNotesCompileComponents();
|
||||||
}
|
}
|
||||||
|
|
||||||
form.find(".js-note-text").focus();
|
form.find(".js-note-text").focus();
|
||||||
|
|
|
@ -45,15 +45,15 @@
|
||||||
this.content.hide();
|
this.content.hide();
|
||||||
this.$toggleIcon.addClass('fa-caret-right').removeClass('fa-caret-down');
|
this.$toggleIcon.addClass('fa-caret-right').removeClass('fa-caret-down');
|
||||||
this.collapsedContent.show();
|
this.collapsedContent.show();
|
||||||
if (typeof DiffNotesApp !== 'undefined') {
|
if (typeof gl.diffNotesCompileComponents !== 'undefined') {
|
||||||
DiffNotesApp.compileComponents();
|
gl.diffNotesCompileComponents();
|
||||||
}
|
}
|
||||||
} else if (this.content) {
|
} else if (this.content) {
|
||||||
this.collapsedContent.hide();
|
this.collapsedContent.hide();
|
||||||
this.content.show();
|
this.content.show();
|
||||||
this.$toggleIcon.addClass('fa-caret-down').removeClass('fa-caret-right');
|
this.$toggleIcon.addClass('fa-caret-down').removeClass('fa-caret-right');
|
||||||
if (typeof DiffNotesApp !== 'undefined') {
|
if (typeof gl.diffNotesCompileComponents !== 'undefined') {
|
||||||
DiffNotesApp.compileComponents();
|
gl.diffNotesCompileComponents();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.$toggleIcon.addClass('fa-caret-down').removeClass('fa-caret-right');
|
this.$toggleIcon.addClass('fa-caret-down').removeClass('fa-caret-right');
|
||||||
|
@ -76,8 +76,8 @@
|
||||||
}
|
}
|
||||||
_this.collapsedContent.after(_this.content);
|
_this.collapsedContent.after(_this.content);
|
||||||
|
|
||||||
if (typeof DiffNotesApp !== 'undefined') {
|
if (typeof gl.diffNotesCompileComponents !== 'undefined') {
|
||||||
DiffNotesApp.compileComponents();
|
gl.diffNotesCompileComponents();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cb) cb();
|
if (cb) cb();
|
||||||
|
|
|
@ -166,8 +166,12 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.board-list {
|
.board-list-component {
|
||||||
height: calc(100% - 49px);
|
height: calc(100% - 49px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.board-list {
|
||||||
|
height: 100%;
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
list-style: none;
|
list-style: none;
|
||||||
|
@ -175,7 +179,7 @@
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
|
|
||||||
&.is-smaller {
|
&.is-smaller {
|
||||||
height: calc(100% - 185px);
|
height: calc(100% - 136px);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
28
app/views/projects/boards/_show.html.haml
Normal file
28
app/views/projects/boards/_show.html.haml
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
- @no_container = true
|
||||||
|
- @content_class = "issue-boards-content"
|
||||||
|
- page_title "Boards"
|
||||||
|
|
||||||
|
- content_for :page_specific_javascripts do
|
||||||
|
= page_specific_javascript_tag('boards/boards_bundle.js')
|
||||||
|
= page_specific_javascript_tag('boards/test_utils/simulate_drag.js') if Rails.env.test?
|
||||||
|
|
||||||
|
%script#js-board-template{ type: "text/x-template" }= render "projects/boards/components/board"
|
||||||
|
%script#js-board-list-template{ type: "text/x-template" }= render "projects/boards/components/board_list"
|
||||||
|
%script#js-board-list-card{ type: "text/x-template" }= render "projects/boards/components/card"
|
||||||
|
|
||||||
|
= render "projects/issues/head"
|
||||||
|
|
||||||
|
= render 'shared/issuable/filter', type: :boards
|
||||||
|
|
||||||
|
#board-app.boards-app{ "v-cloak" => true, data: board_data }
|
||||||
|
.boards-list{ ":class" => "{ 'is-compact': detailIssueVisible }" }
|
||||||
|
.boards-app-loading.text-center{ "v-if" => "loading" }
|
||||||
|
= icon("spinner spin")
|
||||||
|
%board{ "v-cloak" => true,
|
||||||
|
"v-for" => "list in state.lists",
|
||||||
|
"ref" => "board",
|
||||||
|
":list" => "list",
|
||||||
|
":disabled" => "disabled",
|
||||||
|
":issue-link-base" => "issueLinkBase",
|
||||||
|
":key" => "_uid" }
|
||||||
|
= render "projects/boards/components/sidebar"
|
|
@ -1,5 +1,5 @@
|
||||||
%board-blank-state{ "inline-template" => true,
|
%board-blank-state{ "inline-template" => true,
|
||||||
"v-if" => "list.id == 'blank'" }
|
"v-if" => 'list.id == "blank"' }
|
||||||
.board-blank-state
|
.board-blank-state
|
||||||
%p
|
%p
|
||||||
Add the following default lists to your Issue Board with one click:
|
Add the following default lists to your Issue Board with one click:
|
||||||
|
|
|
@ -1,80 +1,34 @@
|
||||||
%board{ "inline-template" => true,
|
.board{ ":class" => '{ "is-draggable": !list.preset }',
|
||||||
"v-cloak" => true,
|
":data-id" => "list.id" }
|
||||||
"v-for" => "list in state.lists | orderBy 'position'",
|
.board-inner
|
||||||
"v-ref:board" => true,
|
%header.board-header{ ":class" => '{ "has-border": list.label }', ":style" => "{ borderTopColor: (list.label ? list.label.color : null) }" }
|
||||||
":list" => "list",
|
%h3.board-title.js-board-handle{ ":class" => '{ "user-can-drag": (!disabled && !list.preset) }' }
|
||||||
":disabled" => "disabled",
|
%span.has-tooltip{ ":title" => '(list.label ? list.label.description : "")',
|
||||||
":issue-link-base" => "issueLinkBase",
|
data: { container: "body", placement: "bottom" } }
|
||||||
"track-by" => "_uid" }
|
{{ list.title }}
|
||||||
.board{ ":class" => "{ 'is-draggable': !list.preset }",
|
.board-issue-count-holder.pull-right.clearfix{ "v-if" => 'list.type !== "blank"' }
|
||||||
":data-id" => "list.id" }
|
%span.board-issue-count.pull-left{ ":class" => '{ "has-btn": list.type !== "done" }' }
|
||||||
.board-inner
|
{{ list.issuesSize }}
|
||||||
%header.board-header{ ":class" => "{ 'has-border': list.label }", ":style" => "{ borderTopColor: (list.label ? list.label.color : null) }" }
|
- if can?(current_user, :admin_issue, @project)
|
||||||
%h3.board-title.js-board-handle{ ":class" => "{ 'user-can-drag': (!disabled && !list.preset) }" }
|
%button.btn.btn-small.btn-default.pull-right.has-tooltip{ type: "button",
|
||||||
%span.has-tooltip{ ":title" => "(list.label ? list.label.description : '')",
|
"@click" => "showNewIssueForm",
|
||||||
data: { container: "body", placement: "bottom" } }
|
"v-if" => 'list.type !== "done"',
|
||||||
{{ list.title }}
|
"aria-label" => "Add an issue",
|
||||||
.board-issue-count-holder.pull-right.clearfix{ "v-if" => "list.type !== 'blank'" }
|
"title" => "Add an issue",
|
||||||
%span.board-issue-count.pull-left{ ":class" => "{ 'has-btn': list.type !== 'done' }" }
|
data: { placement: "top", container: "body" } }
|
||||||
{{ list.issuesSize }}
|
= icon("plus")
|
||||||
- if can?(current_user, :admin_issue, @project)
|
- if can?(current_user, :admin_list, @project)
|
||||||
%button.btn.btn-small.btn-default.pull-right.has-tooltip{ type: "button",
|
%board-delete{ "inline-template" => true,
|
||||||
"@click" => "showNewIssueForm",
|
|
||||||
"v-if" => "list.type !== 'done'",
|
|
||||||
"aria-label" => "Add an issue",
|
|
||||||
"title" => "Add an issue",
|
|
||||||
data: { placement: "top", container: "body" } }
|
|
||||||
= icon("plus")
|
|
||||||
- if can?(current_user, :admin_list, @project)
|
|
||||||
%board-delete{ "inline-template" => true,
|
|
||||||
":list" => "list",
|
|
||||||
"v-if" => "!list.preset && list.id" }
|
|
||||||
%button.board-delete.has-tooltip.pull-right{ type: "button", title: "Delete list", "aria-label" => "Delete list", data: { placement: "bottom" }, "@click.stop" => "deleteBoard" }
|
|
||||||
= icon("trash")
|
|
||||||
%board-list{ "inline-template" => true,
|
|
||||||
"v-if" => "list.type !== 'blank'",
|
|
||||||
":list" => "list",
|
|
||||||
":issues" => "list.issues",
|
|
||||||
":loading" => "list.loading",
|
|
||||||
":disabled" => "disabled",
|
|
||||||
":show-issue-form.sync" => "showIssueForm",
|
|
||||||
":issue-link-base" => "issueLinkBase" }
|
|
||||||
.board-list-loading.text-center{ "v-if" => "loading" }
|
|
||||||
= icon("spinner spin")
|
|
||||||
- if can? current_user, :create_issue, @project
|
|
||||||
%board-new-issue{ "inline-template" => true,
|
|
||||||
":list" => "list",
|
":list" => "list",
|
||||||
":show-issue-form.sync" => "showIssueForm",
|
"v-if" => "!list.preset && list.id" }
|
||||||
"v-show" => "list.type !== 'done' && showIssueForm" }
|
%button.board-delete.has-tooltip.pull-right{ type: "button", title: "Delete list", "aria-label" => "Delete list", data: { placement: "bottom" }, "@click.stop" => "deleteBoard" }
|
||||||
.card.board-new-issue-form
|
= icon("trash")
|
||||||
%form{ "@submit" => "submit($event)" }
|
%board-list{ "v-if" => 'list.type !== "blank"',
|
||||||
.flash-container{ "v-if" => "error" }
|
":list" => "list",
|
||||||
.flash-alert
|
":issues" => "list.issues",
|
||||||
An error occured. Please try again.
|
":loading" => "list.loading",
|
||||||
%label.label-light{ ":for" => "list.id + '-title'" }
|
":disabled" => "disabled",
|
||||||
Title
|
":issue-link-base" => "issueLinkBase",
|
||||||
%input.form-control{ type: "text",
|
"ref" => "board-list" }
|
||||||
"v-model" => "title",
|
- if can?(current_user, :admin_list, @project)
|
||||||
"v-el:input" => true,
|
= render "projects/boards/components/blank_state"
|
||||||
":id" => "list.id + '-title'" }
|
|
||||||
.clearfix.prepend-top-10
|
|
||||||
%button.btn.btn-success.pull-left{ type: "submit",
|
|
||||||
":disabled" => "title === ''",
|
|
||||||
"v-el:submit-button" => true }
|
|
||||||
Submit issue
|
|
||||||
%button.btn.btn-default.pull-right{ type: "button",
|
|
||||||
"@click" => "cancel" }
|
|
||||||
Cancel
|
|
||||||
%ul.board-list{ "v-el:list" => true,
|
|
||||||
"v-show" => "!loading",
|
|
||||||
":data-board" => "list.id",
|
|
||||||
":class" => "{ 'is-smaller': showIssueForm }" }
|
|
||||||
= render "projects/boards/components/card"
|
|
||||||
%li.board-list-count.text-center{ "v-if" => "showCount" }
|
|
||||||
= icon("spinner spin", "v-show" => "list.loadingMore" )
|
|
||||||
%span{ "v-if" => "list.issues.length === list.issuesSize" }
|
|
||||||
Showing all issues
|
|
||||||
%span{ "v-else" => true }
|
|
||||||
Showing {{ list.issues.length }} of {{ list.issuesSize }} issues
|
|
||||||
- if can?(current_user, :admin_list, @project)
|
|
||||||
= render "projects/boards/components/blank_state"
|
|
||||||
|
|
44
app/views/projects/boards/components/_board_list.html.haml
Normal file
44
app/views/projects/boards/components/_board_list.html.haml
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
.board-list-component
|
||||||
|
.board-list-loading.text-center{ "v-if" => "loading" }
|
||||||
|
= icon("spinner spin")
|
||||||
|
- if can? current_user, :create_issue, @project
|
||||||
|
%board-new-issue{ "inline-template" => true,
|
||||||
|
":list" => "list",
|
||||||
|
"v-if" => 'list.type !== "done" && showIssueForm' }
|
||||||
|
.card.board-new-issue-form
|
||||||
|
%form{ "@submit" => "submit($event)" }
|
||||||
|
.flash-container{ "v-if" => "error" }
|
||||||
|
.flash-alert
|
||||||
|
An error occured. Please try again.
|
||||||
|
%label.label-light{ ":for" => 'list.id + "-title"' }
|
||||||
|
Title
|
||||||
|
%input.form-control{ type: "text",
|
||||||
|
"v-model" => "title",
|
||||||
|
"ref" => "input",
|
||||||
|
":id" => 'list.id + "-title"' }
|
||||||
|
.clearfix.prepend-top-10
|
||||||
|
%button.btn.btn-success.pull-left{ type: "submit",
|
||||||
|
":disabled" => 'title === ""',
|
||||||
|
"ref" => "submit-button" }
|
||||||
|
Submit issue
|
||||||
|
%button.btn.btn-default.pull-right{ type: "button",
|
||||||
|
"@click" => "cancel" }
|
||||||
|
Cancel
|
||||||
|
%ul.board-list{ "ref" => "list",
|
||||||
|
"v-show" => "!loading",
|
||||||
|
":data-board" => "list.id",
|
||||||
|
":class" => '{ "is-smaller": showIssueForm }' }
|
||||||
|
%board-card{ "v-for" => "(issue, index) in orderedIssues",
|
||||||
|
"ref" => "issue",
|
||||||
|
":index" => "index",
|
||||||
|
":list" => "list",
|
||||||
|
":issue" => "issue",
|
||||||
|
":issue-link-base" => "issueLinkBase",
|
||||||
|
":disabled" => "disabled",
|
||||||
|
"key" => "id" }
|
||||||
|
%li.board-list-count.text-center{ "v-if" => "showCount" }
|
||||||
|
= icon("spinner spin", "v-show" => "list.loadingMore" )
|
||||||
|
%span{ "v-if" => "list.issues.length === list.issuesSize" }
|
||||||
|
Showing all issues
|
||||||
|
%span{ "v-else" => true }
|
||||||
|
Showing {{ list.issues.length }} of {{ list.issuesSize }} issues
|
|
@ -1,36 +1,26 @@
|
||||||
%board-card{ "inline-template" => true,
|
%li.card{ ":class" => '{ "user-can-drag": !disabled && issue.id, "is-disabled": disabled || !issue.id, "is-active": issueDetailVisible }',
|
||||||
"v-for" => "issue in issues | orderBy 'priority'",
|
":index" => "index",
|
||||||
"v-ref:issue" => true,
|
"@mousedown" => "mouseDown",
|
||||||
":index" => "$index",
|
"@mouseup" => "showIssue($event)" }
|
||||||
":list" => "list",
|
%h4.card-title
|
||||||
":issue" => "issue",
|
= icon("eye-slash", class: "confidential-icon", "v-if" => "issue.confidential")
|
||||||
":issue-link-base" => "issueLinkBase",
|
%a{ ":href" => 'issueLinkBase + "/" + issue.id',
|
||||||
":disabled" => "disabled",
|
":title" => "issue.title" }
|
||||||
"track-by" => "id" }
|
{{ issue.title }}
|
||||||
%li.card{ ":class" => "{ 'user-can-drag': !disabled && issue.id, 'is-disabled': disabled || !issue.id, 'is-active': issueDetailVisible }",
|
.card-footer
|
||||||
":index" => "index",
|
%span.card-number{ "v-if" => "issue.id" }
|
||||||
"@mousedown" => "mouseDown",
|
= precede '#' do
|
||||||
"@mouseMove" => "mouseMove",
|
{{ issue.id }}
|
||||||
"@mouseup" => "showIssue($event)" }
|
%a.has-tooltip{ ":href" => "\"#{root_path}\" + issue.assignee.username",
|
||||||
%h4.card-title
|
":title" => '"Assigned to " + issue.assignee.name',
|
||||||
= icon("eye-slash", class: "confidential-icon", "v-if" => "issue.confidential")
|
"v-if" => "issue.assignee",
|
||||||
%a{ ":href" => "issueLinkBase + '/' + issue.id",
|
data: { container: 'body' } }
|
||||||
":title" => "issue.title" }
|
%img.avatar.avatar-inline.s20{ ":src" => "issue.assignee.avatar", width: 20, height: 20 }
|
||||||
{{ issue.title }}
|
%button.label.color-label.has-tooltip{ "v-for" => "label in issue.labels",
|
||||||
.card-footer
|
type: "button",
|
||||||
%span.card-number{ "v-if" => "issue.id" }
|
"v-if" => "(!list.label || label.id !== list.label.id)",
|
||||||
= precede '#' do
|
"@click" => "filterByLabel(label, $event)",
|
||||||
{{ issue.id }}
|
":style" => "{ backgroundColor: label.color, color: label.textColor }",
|
||||||
%a.has-tooltip{ ":href" => "'#{root_path}' + issue.assignee.username",
|
":title" => "label.description",
|
||||||
":title" => "'Assigned to ' + issue.assignee.name",
|
data: { container: 'body' } }
|
||||||
"v-if" => "issue.assignee",
|
{{ label.title }}
|
||||||
data: { container: 'body' } }
|
|
||||||
%img.avatar.avatar-inline.s20{ ":src" => "issue.assignee.avatar", width: 20, height: 20 }
|
|
||||||
%button.label.color-label.has-tooltip{ "v-for" => "label in issue.labels",
|
|
||||||
type: "button",
|
|
||||||
"v-if" => "(!list.label || label.id !== list.label.id)",
|
|
||||||
"@click" => "filterByLabel(label, $event)",
|
|
||||||
":style" => "{ backgroundColor: label.color, color: label.textColor }",
|
|
||||||
":title" => "label.description",
|
|
||||||
data: { container: 'body' } }
|
|
||||||
{{ label.title }}
|
|
||||||
|
|
|
@ -1,18 +1 @@
|
||||||
- @no_container = true
|
= render "show"
|
||||||
- @content_class = "issue-boards-content"
|
|
||||||
- page_title "Boards"
|
|
||||||
|
|
||||||
- content_for :page_specific_javascripts do
|
|
||||||
= page_specific_javascript_tag('boards/boards_bundle.js')
|
|
||||||
= page_specific_javascript_tag('boards/test_utils/simulate_drag.js') if Rails.env.test?
|
|
||||||
|
|
||||||
= render "projects/issues/head"
|
|
||||||
|
|
||||||
= render 'shared/issuable/filter', type: :boards
|
|
||||||
|
|
||||||
#board-app.boards-app{ "v-cloak" => true, data: board_data }
|
|
||||||
.boards-list{ ":class" => "{ 'is-compact': detailIssueVisible }" }
|
|
||||||
.boards-app-loading.text-center{ "v-if" => "loading" }
|
|
||||||
= icon("spinner spin")
|
|
||||||
= render "projects/boards/components/board"
|
|
||||||
= render "projects/boards/components/sidebar"
|
|
||||||
|
|
|
@ -1,18 +1 @@
|
||||||
- @no_container = true
|
= render "show"
|
||||||
- @content_class = "issue-boards-content"
|
|
||||||
- page_title "Boards"
|
|
||||||
|
|
||||||
- content_for :page_specific_javascripts do
|
|
||||||
= page_specific_javascript_tag('boards/boards_bundle.js')
|
|
||||||
= page_specific_javascript_tag('boards/test_utils/simulate_drag.js') if Rails.env.test?
|
|
||||||
|
|
||||||
= render "projects/issues/head"
|
|
||||||
|
|
||||||
= render 'shared/issuable/filter', type: :boards
|
|
||||||
|
|
||||||
#board-app.boards-app{ "v-cloak" => true, data: board_data }
|
|
||||||
.boards-list{ ":class" => "{ 'is-compact': detailIssueVisible }" }
|
|
||||||
.boards-app-loading.text-center{ "v-if" => "loading" }
|
|
||||||
= icon("spinner spin")
|
|
||||||
= render "projects/boards/components/board"
|
|
||||||
= render "projects/boards/components/sidebar"
|
|
||||||
|
|
|
@ -74,14 +74,15 @@
|
||||||
%span.badge= @merge_request.diff_size
|
%span.badge= @merge_request.diff_size
|
||||||
%li#resolve-count-app.line-resolve-all-container.pull-right.prepend-top-10.hidden-xs{ "v-cloak" => true }
|
%li#resolve-count-app.line-resolve-all-container.pull-right.prepend-top-10.hidden-xs{ "v-cloak" => true }
|
||||||
%resolve-count{ "inline-template" => true, ":logged-out" => "#{current_user.nil?}" }
|
%resolve-count{ "inline-template" => true, ":logged-out" => "#{current_user.nil?}" }
|
||||||
.line-resolve-all{ "v-show" => "discussionCount > 0",
|
%div
|
||||||
":class" => "{ 'has-next-btn': !loggedOut && resolvedDiscussionCount !== discussionCount }" }
|
.line-resolve-all{ "v-show" => "discussionCount > 0",
|
||||||
%span.line-resolve-btn.is-disabled{ type: "button",
|
":class" => "{ 'has-next-btn': !loggedOut && resolvedDiscussionCount !== discussionCount }" }
|
||||||
":class" => "{ 'is-active': resolvedDiscussionCount === discussionCount }" }
|
%span.line-resolve-btn.is-disabled{ type: "button",
|
||||||
= render "shared/icons/icon_status_success.svg"
|
":class" => "{ 'is-active': resolvedDiscussionCount === discussionCount }" }
|
||||||
%span.line-resolve-text
|
= render "shared/icons/icon_status_success.svg"
|
||||||
{{ resolvedDiscussionCount }}/{{ discussionCount }} {{ discussionCount | pluralize 'discussion' }} resolved
|
%span.line-resolve-text
|
||||||
= render "discussions/jump_to_next"
|
{{ resolvedDiscussionCount }}/{{ discussionCount }} {{ resolvedCountText }} resolved
|
||||||
|
= render "discussions/jump_to_next"
|
||||||
|
|
||||||
.tab-content#diff-notes-app
|
.tab-content#diff-notes-app
|
||||||
#notes.notes.tab-pane.voting_notes
|
#notes.notes.tab-pane.voting_notes
|
||||||
|
|
|
@ -30,11 +30,8 @@
|
||||||
.diff-wrap-lines.code.file-content.js-syntax-highlight{"v-show" => "!isParallel && file.resolveMode === 'interactive' && file.type === 'text'" }
|
.diff-wrap-lines.code.file-content.js-syntax-highlight{"v-show" => "!isParallel && file.resolveMode === 'interactive' && file.type === 'text'" }
|
||||||
= render partial: "projects/merge_requests/conflicts/components/inline_conflict_lines"
|
= render partial: "projects/merge_requests/conflicts/components/inline_conflict_lines"
|
||||||
.diff-wrap-lines.code.file-content.js-syntax-highlight{"v-show" => "isParallel && file.resolveMode === 'interactive' && file.type === 'text'" }
|
.diff-wrap-lines.code.file-content.js-syntax-highlight{"v-show" => "isParallel && file.resolveMode === 'interactive' && file.type === 'text'" }
|
||||||
= render partial: "projects/merge_requests/conflicts/components/parallel_conflict_lines"
|
%parallel-conflict-lines{ ":file" => "file" }
|
||||||
%div{"v-show" => "file.resolveMode === 'edit' || file.type === 'text-editor'"}
|
%div{"v-show" => "file.resolveMode === 'edit' || file.type === 'text-editor'"}
|
||||||
= render partial: "projects/merge_requests/conflicts/components/diff_file_editor"
|
= render partial: "projects/merge_requests/conflicts/components/diff_file_editor"
|
||||||
|
|
||||||
= render partial: "projects/merge_requests/conflicts/submit_form"
|
= render partial: "projects/merge_requests/conflicts/submit_form"
|
||||||
|
|
||||||
-# Components
|
|
||||||
= render partial: 'projects/merge_requests/conflicts/components/parallel_conflict_line'
|
|
||||||
|
|
|
@ -5,11 +5,10 @@
|
||||||
%a {{line.new_line}}
|
%a {{line.new_line}}
|
||||||
%td.diff-line-num.old_line{":class" => "lineCssClass(line)", "v-if" => "!line.isHeader"}
|
%td.diff-line-num.old_line{":class" => "lineCssClass(line)", "v-if" => "!line.isHeader"}
|
||||||
%a {{line.old_line}}
|
%a {{line.old_line}}
|
||||||
%td.line_content{":class" => "lineCssClass(line)", "v-if" => "!line.isHeader"}
|
%td.line_content{":class" => "lineCssClass(line)", "v-if" => "!line.isHeader", "v-html" => "line.richText"}
|
||||||
{{{line.richText}}}
|
|
||||||
%td.diff-line-num.header{":class" => "lineCssClass(line)", "v-if" => "line.isHeader"}
|
%td.diff-line-num.header{":class" => "lineCssClass(line)", "v-if" => "line.isHeader"}
|
||||||
%td.diff-line-num.header{":class" => "lineCssClass(line)", "v-if" => "line.isHeader"}
|
%td.diff-line-num.header{":class" => "lineCssClass(line)", "v-if" => "line.isHeader"}
|
||||||
%td.line_content.header{":class" => "lineCssClass(line)", "v-if" => "line.isHeader"}
|
%td.line_content.header{":class" => "lineCssClass(line)", "v-if" => "line.isHeader"}
|
||||||
%strong {{{line.richText}}}
|
%strong{"v-html" => "line.richText"}
|
||||||
%button.btn{ "@click" => "handleSelected(file, line.id, line.section)" }
|
%button.btn{ "@click" => "handleSelected(file, line.id, line.section)" }
|
||||||
{{line.buttonTitle}}
|
{{line.buttonTitle}}
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
%script{"id" => 'parallel-conflict-line', "type" => "text/x-template"}
|
|
||||||
%td.diff-line-num.header{":class" => "lineCssClass(line)", "v-if" => "line.isHeader"}
|
|
||||||
%td.line_content.header{":class" => "lineCssClass(line)", "v-if" => "line.isHeader"}
|
|
||||||
%strong {{line.richText}}
|
|
||||||
%button.btn{"@click" => "handleSelected(file, line.id, line.section)"}
|
|
||||||
{{line.buttonTitle}}
|
|
||||||
%td.diff-line-num.old_line{":class" => "lineCssClass(line)", "v-if" => "!line.isHeader"}
|
|
||||||
{{line.lineNumber}}
|
|
||||||
%td.line_content.parallel{":class" => "lineCssClass(line)", "v-if" => "!line.isHeader"}
|
|
||||||
{{{line.richText}}}
|
|
|
@ -1,4 +0,0 @@
|
||||||
%parallel-conflict-lines{"inline-template" => "true", ":file" => "file"}
|
|
||||||
%table
|
|
||||||
%tr.line_holder.parallel{"v-for" => "section in file.parallelLines"}
|
|
||||||
%td{"is"=>"parallel-conflict-line", "v-for" => "line in section", ":line" => "line", ":file" => "file"}
|
|
|
@ -32,7 +32,7 @@
|
||||||
"resolved-by" => "#{note.resolved_by.try(:name)}",
|
"resolved-by" => "#{note.resolved_by.try(:name)}",
|
||||||
"v-show" => "#{can_resolve || note.resolved?}",
|
"v-show" => "#{can_resolve || note.resolved?}",
|
||||||
"inline-template" => true,
|
"inline-template" => true,
|
||||||
"v-ref:note_#{note.id}" => true }
|
"ref" => "note_#{note.id}" }
|
||||||
|
|
||||||
.note-action-button
|
.note-action-button
|
||||||
= icon("spin spinner", "v-show" => "loading")
|
= icon("spin spinner", "v-show" => "loading")
|
||||||
|
@ -43,7 +43,7 @@
|
||||||
"@click" => "resolve",
|
"@click" => "resolve",
|
||||||
":title" => "buttonText",
|
":title" => "buttonText",
|
||||||
"v-show" => "!loading",
|
"v-show" => "!loading",
|
||||||
"v-el:button" => true }
|
":ref" => "'button'" }
|
||||||
|
|
||||||
= render "shared/icons/icon_status_success.svg"
|
= render "shared/icons/icon_status_success.svg"
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ describe 'Issue Boards new issue', feature: true, js: true do
|
||||||
|
|
||||||
click_button 'Cancel'
|
click_button 'Cancel'
|
||||||
|
|
||||||
expect(page).to have_selector('.board-new-issue-form', visible: false)
|
expect(page).not_to have_selector('.board-new-issue-form')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -69,8 +69,6 @@ feature 'Diff notes resolve', feature: true, js: true do
|
||||||
|
|
||||||
page.within '.diff-content .note' do
|
page.within '.diff-content .note' do
|
||||||
expect(page).to have_selector('.line-resolve-btn.is-active')
|
expect(page).to have_selector('.line-resolve-btn.is-active')
|
||||||
|
|
||||||
expect(find('.line-resolve-btn')['data-original-title']).to eq("Resolved by #{user.name}")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
page.within '.line-resolve-all-container' do
|
page.within '.line-resolve-all-container' do
|
||||||
|
|
17170
vendor/assets/javascripts/vue.full.js
vendored
17170
vendor/assets/javascripts/vue.full.js
vendored
File diff suppressed because it is too large
Load diff
10
vendor/assets/javascripts/vue.min.js
vendored
10
vendor/assets/javascripts/vue.min.js
vendored
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue