Commit 5c847f1a authored by Phil Hughes's avatar Phil Hughes

Merge branch 'ce-5787-extract-ee-boards' into 'master'

Port of EE refactoring to extract EE lines from boards

See merge request gitlab-org/gitlab-ce!19486
parents 7c540395 21843c2c
...@@ -28,16 +28,22 @@ export default { ...@@ -28,16 +28,22 @@ export default {
}, },
}, },
methods: { methods: {
buildUpdateRequest(list) {
return {
add_label_ids: [list.label.id],
};
},
addIssues() { addIssues() {
const firstListIndex = 1; const firstListIndex = 1;
const list = this.modal.selectedList || this.state.lists[firstListIndex]; const list = this.modal.selectedList || this.state.lists[firstListIndex];
const selectedIssues = ModalStore.getSelectedIssues(); const selectedIssues = ModalStore.getSelectedIssues();
const issueIds = selectedIssues.map(issue => issue.id); const issueIds = selectedIssues.map(issue => issue.id);
const req = this.buildUpdateRequest(list);
// Post the data to the backend // Post the data to the backend
gl.boardService.bulkUpdate(issueIds, { gl.boardService
add_label_ids: [list.label.id], .bulkUpdate(issueIds, req)
}).catch(() => { .catch(() => {
Flash(__('Failed to update issues, please try again.')); Flash(__('Failed to update issues, please try again.'));
selectedIssues.forEach((issue) => { selectedIssues.forEach((issue) => {
......
...@@ -121,8 +121,7 @@ ...@@ -121,8 +121,7 @@
<div <div
v-if="issuesCount > 0 && issues.length === 0" v-if="issuesCount > 0 && issues.length === 0"
class="empty-state add-issues-empty-state-filter text-center"> class="empty-state add-issues-empty-state-filter text-center">
<div <div class="svg-content">
class="svg-content">
<img :src="emptyStateSvg" /> <img :src="emptyStateSvg" />
</div> </div>
<div class="text-content"> <div class="text-content">
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
const Store = gl.issueBoards.BoardsStore; const Store = gl.issueBoards.BoardsStore;
export default { export default Vue.extend({
props: { props: {
issue: { issue: {
type: Object, type: Object,
...@@ -25,19 +25,16 @@ ...@@ -25,19 +25,16 @@
removeIssue() { removeIssue() {
const { issue } = this; const { issue } = this;
const lists = issue.getLists(); const lists = issue.getLists();
const listLabelIds = lists.map(list => list.label.id); const req = this.buildPatchRequest(issue, lists);
let labelIds = issue.labels.map(label => label.id).filter(id => !listLabelIds.includes(id));
if (labelIds.length === 0) {
labelIds = [''];
}
const data = { const data = {
issue: { issue: this.seedPatchRequest(issue, req),
label_ids: labelIds,
},
}; };
if (data.issue.label_ids.length === 0) {
data.issue.label_ids = [''];
}
// Post the remove data // Post the remove data
Vue.http.patch(this.updateUrl, data).catch(() => { Vue.http.patch(this.updateUrl, data).catch(() => {
Flash(__('Failed to remove issue from board, please try again.')); Flash(__('Failed to remove issue from board, please try again.'));
...@@ -54,8 +51,30 @@ ...@@ -54,8 +51,30 @@
Store.detail.issue = {}; Store.detail.issue = {};
}, },
}, /**
* Build the default patch request.
*/
buildPatchRequest(issue, lists) {
const listLabelIds = lists.map(list => list.label.id);
const labelIds = issue.labels
.map(label => label.id)
.filter(id => !listLabelIds.includes(id));
return {
label_ids: labelIds,
}; };
},
/**
* Seed the given patch request.
*
* (This is overridden in EE)
*/
seedPatchRequest(issue, req) {
return req;
},
},
});
</script> </script>
<template> <template>
<div <div
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
/* global ListAssignee */ /* global ListAssignee */
import Vue from 'vue'; import Vue from 'vue';
import '~/vue_shared/models/label';
import IssueProject from './project'; import IssueProject from './project';
class ListIssue { class ListIssue {
......
...@@ -7,6 +7,24 @@ import queryData from '../utils/query_data'; ...@@ -7,6 +7,24 @@ import queryData from '../utils/query_data';
const PER_PAGE = 20; const PER_PAGE = 20;
const TYPES = {
backlog: {
isPreset: true,
isExpandable: true,
isBlank: false,
},
closed: {
isPreset: true,
isExpandable: true,
isBlank: false,
},
blank: {
isPreset: true,
isExpandable: false,
isBlank: true,
},
};
class List { class List {
constructor(obj, defaultAvatar) { constructor(obj, defaultAvatar) {
this.id = obj.id; this.id = obj.id;
...@@ -14,8 +32,10 @@ class List { ...@@ -14,8 +32,10 @@ class List {
this.position = obj.position; this.position = obj.position;
this.title = obj.title; this.title = obj.title;
this.type = obj.list_type; this.type = obj.list_type;
this.preset = ['backlog', 'closed', 'blank'].indexOf(this.type) > -1;
this.isExpandable = ['backlog', 'closed'].indexOf(this.type) > -1; const typeInfo = this.getTypeInfo(this.type);
this.preset = !!typeInfo.isPreset;
this.isExpandable = !!typeInfo.isExpandable;
this.isExpanded = true; this.isExpanded = true;
this.page = 1; this.page = 1;
this.loading = true; this.loading = true;
...@@ -31,7 +51,7 @@ class List { ...@@ -31,7 +51,7 @@ class List {
this.title = this.assignee.name; this.title = this.assignee.name;
} }
if (this.type !== 'blank' && this.id) { if (!typeInfo.isBlank && this.id) {
this.getIssues().catch(() => { this.getIssues().catch(() => {
// TODO: handle request error // TODO: handle request error
}); });
...@@ -107,7 +127,7 @@ class List { ...@@ -107,7 +127,7 @@ class List {
return gl.boardService return gl.boardService
.getIssuesForList(this.id, data) .getIssuesForList(this.id, data)
.then(res => res.data) .then(res => res.data)
.then((data) => { .then(data => {
this.loading = false; this.loading = false;
this.issuesSize = data.size; this.issuesSize = data.size;
...@@ -126,18 +146,7 @@ class List { ...@@ -126,18 +146,7 @@ class List {
return gl.boardService return gl.boardService
.newIssue(this.id, issue) .newIssue(this.id, issue)
.then(res => res.data) .then(res => res.data)
.then((data) => { .then(data => this.onNewIssueResponse(issue, data));
issue.id = data.id;
issue.iid = data.iid;
issue.project = data.project;
issue.path = data.real_path;
issue.referencePath = data.reference_path;
if (this.issuesSize > 1) {
const moveBeforeId = this.issues[1].id;
gl.boardService.moveIssue(issue.id, null, null, null, moveBeforeId);
}
});
} }
createIssues(data) { createIssues(data) {
...@@ -217,6 +226,25 @@ class List { ...@@ -217,6 +226,25 @@ class List {
return !matchesRemove; return !matchesRemove;
}); });
} }
getTypeInfo (type) {
return TYPES[type] || {};
}
onNewIssueResponse (issue, data) {
issue.id = data.id;
issue.iid = data.iid;
issue.project = data.project;
issue.path = data.real_path;
issue.referencePath = data.reference_path;
if (this.issuesSize > 1) {
const moveBeforeId = this.issues[1].id;
gl.boardService.moveIssue(issue.id, null, null, null, moveBeforeId);
}
}
} }
window.List = List; window.List = List;
export default List;
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
import $ from 'jquery'; import $ from 'jquery';
import _ from 'underscore'; import _ from 'underscore';
import { __ } from '~/locale'; import { __ } from '~/locale';
import '~/gl_dropdown';
import axios from './lib/utils/axios_utils'; import axios from './lib/utils/axios_utils';
import { timeFor } from './lib/utils/datetime_utility'; import { timeFor } from './lib/utils/datetime_utility';
import ModalStore from './boards/stores/modal_store'; import ModalStore from './boards/stores/modal_store';
...@@ -251,3 +252,5 @@ export default class MilestoneSelect { ...@@ -251,3 +252,5 @@ export default class MilestoneSelect {
}); });
} }
} }
window.MilestoneSelect = MilestoneSelect;
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