Removed Masonry, instead uses groups of data
Added some error handling which reverts the frontend data changes & notifies the user
This commit is contained in:
parent
b4113dba03
commit
4428bb27b7
16 changed files with 154 additions and 2551 deletions
|
@ -5,7 +5,6 @@
|
||||||
//= require vue
|
//= require vue
|
||||||
//= require vue-resource
|
//= require vue-resource
|
||||||
//= require Sortable
|
//= require Sortable
|
||||||
//= require masonry
|
|
||||||
//= require_tree ./models
|
//= require_tree ./models
|
||||||
//= require_tree ./stores
|
//= require_tree ./stores
|
||||||
//= require_tree ./services
|
//= require_tree ./services
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
filterByLabel(label, e) {
|
filterByLabel(label, e) {
|
||||||
let labelToggleText = label.title;
|
let labelToggleText = label.title;
|
||||||
const labelIndex = Store.state.filters.label_name.indexOf(label.title);
|
const labelIndex = Store.state.filters.label_name.indexOf(label.title);
|
||||||
$(e.target).tooltip('hide');
|
$(e.currentTarget).tooltip('hide');
|
||||||
|
|
||||||
if (labelIndex === -1) {
|
if (labelIndex === -1) {
|
||||||
Store.state.filters.label_name.push(label.title);
|
Store.state.filters.label_name.push(label.title);
|
||||||
|
@ -55,6 +55,12 @@
|
||||||
|
|
||||||
Store.updateFiltersUrl();
|
Store.updateFiltersUrl();
|
||||||
},
|
},
|
||||||
|
labelStyle(label) {
|
||||||
|
return {
|
||||||
|
backgroundColor: label.color,
|
||||||
|
color: label.textColor,
|
||||||
|
};
|
||||||
|
},
|
||||||
},
|
},
|
||||||
template: `
|
template: `
|
||||||
<div>
|
<div>
|
||||||
|
@ -93,7 +99,7 @@
|
||||||
type="button"
|
type="button"
|
||||||
v-if="showLabel(label)"
|
v-if="showLabel(label)"
|
||||||
@click="filterByLabel(label, $event)"
|
@click="filterByLabel(label, $event)"
|
||||||
:style="{ backgroundColor: label.color, color: label.textColor }"
|
:style="labelStyle(label)"
|
||||||
:title="label.description"
|
:title="label.description"
|
||||||
data-container="body">
|
data-container="body">
|
||||||
{{ label.title }}
|
{{ label.title }}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
|
/* eslint-disable no-new */
|
||||||
//= require ./lists_dropdown
|
//= require ./lists_dropdown
|
||||||
/* global Vue */
|
/* global Vue */
|
||||||
|
/* global Flash */
|
||||||
(() => {
|
(() => {
|
||||||
const ModalStore = gl.issueBoards.ModalStore;
|
const ModalStore = gl.issueBoards.ModalStore;
|
||||||
|
|
||||||
|
@ -15,7 +17,7 @@
|
||||||
submitText() {
|
submitText() {
|
||||||
const count = ModalStore.selectedCount();
|
const count = ModalStore.selectedCount();
|
||||||
|
|
||||||
return `Add ${count > 0 ? count : ''} issue${count > 1 || !count ? 's' : ''}`;
|
return `Add ${count > 0 ? count : ''} ${gl.text.pluralize('issue', count)}`;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -27,6 +29,13 @@
|
||||||
// Post the data to the backend
|
// Post the data to the backend
|
||||||
gl.boardService.bulkUpdate(issueIds, {
|
gl.boardService.bulkUpdate(issueIds, {
|
||||||
add_label_ids: [list.label.id],
|
add_label_ids: [list.label.id],
|
||||||
|
}).catch(() => {
|
||||||
|
new Flash('Failed to update issues, please try again.', 'alert');
|
||||||
|
|
||||||
|
selectedIssues.forEach((issue) => {
|
||||||
|
list.removeIssue(issue);
|
||||||
|
list.issuesSize -= 1;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Add the issues on the frontend
|
// Add the issues on the frontend
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
(() => {
|
(() => {
|
||||||
const ModalStore = gl.issueBoards.ModalStore;
|
const ModalStore = gl.issueBoards.ModalStore;
|
||||||
|
|
||||||
gl.issueBoards.IssuesModalHeader = Vue.extend({
|
gl.issueBoards.ModalHeader = Vue.extend({
|
||||||
mixins: [gl.issueBoards.ModalMixins],
|
mixins: [gl.issueBoards.ModalMixins],
|
||||||
data() {
|
data() {
|
||||||
return ModalStore.store;
|
return ModalStore.store;
|
||||||
|
@ -16,6 +16,9 @@
|
||||||
|
|
||||||
return 'Deselect all';
|
return 'Deselect all';
|
||||||
},
|
},
|
||||||
|
showSearch() {
|
||||||
|
return this.activeTab === 'all' && !this.loading && this.issuesCount > 0;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
toggleAll() {
|
toggleAll() {
|
||||||
|
@ -45,7 +48,7 @@
|
||||||
<modal-tabs v-if="!loading && issuesCount > 0"></modal-tabs>
|
<modal-tabs v-if="!loading && issuesCount > 0"></modal-tabs>
|
||||||
<div
|
<div
|
||||||
class="add-issues-search append-bottom-10"
|
class="add-issues-search append-bottom-10"
|
||||||
v-if="activeTab == 'all' && !loading && issuesCount > 0">
|
v-if="showSearch">
|
||||||
<input
|
<input
|
||||||
placeholder="Search issues..."
|
placeholder="Search issues..."
|
||||||
class="form-control"
|
class="form-control"
|
||||||
|
|
|
@ -53,10 +53,9 @@
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
searchOperation: _.debounce(function searchOperationDebounce() {
|
searchOperation: _.debounce(function searchOperationDebounce() {
|
||||||
this.issues = [];
|
this.loadIssues(true);
|
||||||
this.loadIssues();
|
|
||||||
}, 500),
|
}, 500),
|
||||||
loadIssues() {
|
loadIssues(clearIssues = false) {
|
||||||
return gl.boardService.getBacklog({
|
return gl.boardService.getBacklog({
|
||||||
search: this.searchTerm,
|
search: this.searchTerm,
|
||||||
page: this.page,
|
page: this.page,
|
||||||
|
@ -64,10 +63,14 @@
|
||||||
}).then((res) => {
|
}).then((res) => {
|
||||||
const data = res.json();
|
const data = res.json();
|
||||||
|
|
||||||
|
if (clearIssues) {
|
||||||
|
this.issues = [];
|
||||||
|
}
|
||||||
|
|
||||||
data.issues.forEach((issueObj) => {
|
data.issues.forEach((issueObj) => {
|
||||||
const issue = new ListIssue(issueObj);
|
const issue = new ListIssue(issueObj);
|
||||||
const foundSelectedIssue = ModalStore.findSelectedIssue(issue);
|
const foundSelectedIssue = ModalStore.findSelectedIssue(issue);
|
||||||
issue.selected = foundSelectedIssue !== undefined;
|
issue.selected = !!foundSelectedIssue;
|
||||||
|
|
||||||
this.issues.push(issue);
|
this.issues.push(issue);
|
||||||
});
|
});
|
||||||
|
@ -75,7 +78,7 @@
|
||||||
this.loadingNewPage = false;
|
this.loadingNewPage = false;
|
||||||
|
|
||||||
if (!this.issuesCount) {
|
if (!this.issuesCount) {
|
||||||
this.issuesCount = this.issues.length;
|
this.issuesCount = data.size;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -88,9 +91,16 @@
|
||||||
|
|
||||||
return this.issuesCount > 0;
|
return this.issuesCount > 0;
|
||||||
},
|
},
|
||||||
|
showEmptyState() {
|
||||||
|
if (!this.loading && this.issuesCount === 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.activeTab === 'selected' && this.selectedIssues.length === 0;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
'modal-header': gl.issueBoards.IssuesModalHeader,
|
'modal-header': gl.issueBoards.ModalHeader,
|
||||||
'modal-list': gl.issueBoards.ModalList,
|
'modal-list': gl.issueBoards.ModalList,
|
||||||
'modal-footer': gl.issueBoards.ModalFooter,
|
'modal-footer': gl.issueBoards.ModalFooter,
|
||||||
'empty-state': gl.issueBoards.ModalEmptyState,
|
'empty-state': gl.issueBoards.ModalEmptyState,
|
||||||
|
@ -106,7 +116,7 @@
|
||||||
:root-path="rootPath"
|
:root-path="rootPath"
|
||||||
v-if="!loading && showList"></modal-list>
|
v-if="!loading && showList"></modal-list>
|
||||||
<empty-state
|
<empty-state
|
||||||
v-if="(!loading && issuesCount === 0) || (activeTab === 'selected' && selectedIssues.length === 0)"
|
v-if="showEmptyState"
|
||||||
:image="blankStateImage"
|
:image="blankStateImage"
|
||||||
:new-issue-path="newIssuePath"></empty-state>
|
:new-issue-path="newIssuePath"></empty-state>
|
||||||
<section
|
<section
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
/* global Vue */
|
/* global Vue */
|
||||||
/* global ListIssue */
|
/* global ListIssue */
|
||||||
/* global Masonry */
|
/* global bp */
|
||||||
(() => {
|
(() => {
|
||||||
let listMasonry;
|
|
||||||
const ModalStore = gl.issueBoards.ModalStore;
|
const ModalStore = gl.issueBoards.ModalStore;
|
||||||
|
|
||||||
gl.issueBoards.ModalList = Vue.extend({
|
gl.issueBoards.ModalList = Vue.extend({
|
||||||
|
@ -21,18 +20,10 @@
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
activeTab() {
|
activeTab() {
|
||||||
this.initMasonry();
|
|
||||||
|
|
||||||
if (this.activeTab === 'all') {
|
if (this.activeTab === 'all') {
|
||||||
ModalStore.purgeUnselectedIssues();
|
ModalStore.purgeUnselectedIssues();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
issues: {
|
|
||||||
handler() {
|
|
||||||
this.initMasonry();
|
|
||||||
},
|
|
||||||
deep: true,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
loopIssues() {
|
loopIssues() {
|
||||||
|
@ -42,8 +33,31 @@
|
||||||
|
|
||||||
return this.selectedIssues;
|
return this.selectedIssues;
|
||||||
},
|
},
|
||||||
|
groupedIssues() {
|
||||||
|
const groups = [];
|
||||||
|
this.loopIssues.forEach((issue, i) => {
|
||||||
|
const index = i % this.columns;
|
||||||
|
|
||||||
|
if (!groups[index]) {
|
||||||
|
groups.push([]);
|
||||||
|
}
|
||||||
|
|
||||||
|
groups[index].push(issue);
|
||||||
|
});
|
||||||
|
|
||||||
|
return groups;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
scrollHandler() {
|
||||||
|
const currentPage = Math.floor(this.issues.length / this.perPage);
|
||||||
|
|
||||||
|
if ((this.scrollTop() > this.scrollHeight() - 100) && !this.loadingNewPage
|
||||||
|
&& currentPage === this.page) {
|
||||||
|
this.loadingNewPage = true;
|
||||||
|
this.page += 1;
|
||||||
|
}
|
||||||
|
},
|
||||||
toggleIssue(e, issue) {
|
toggleIssue(e, issue) {
|
||||||
if (e.target.tagName !== 'A') {
|
if (e.target.tagName !== 'A') {
|
||||||
ModalStore.toggleIssue(issue);
|
ModalStore.toggleIssue(issue);
|
||||||
|
@ -65,40 +79,29 @@
|
||||||
|
|
||||||
return index !== -1;
|
return index !== -1;
|
||||||
},
|
},
|
||||||
initMasonry() {
|
setColumnCount() {
|
||||||
const listScrollTop = this.$refs.list.scrollTop;
|
const breakpoint = bp.getBreakpointSize();
|
||||||
|
|
||||||
this.$nextTick(() => {
|
if (breakpoint === 'lg' || breakpoint === 'md') {
|
||||||
this.destroyMasonry();
|
this.columns = 3;
|
||||||
listMasonry = new Masonry(this.$refs.list, {
|
} else if (breakpoint === 'sm') {
|
||||||
transitionDuration: 0,
|
this.columns = 2;
|
||||||
});
|
} else {
|
||||||
|
this.columns = 1;
|
||||||
this.$refs.list.scrollTop = listScrollTop;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
destroyMasonry() {
|
|
||||||
if (listMasonry) {
|
|
||||||
listMasonry.destroy();
|
|
||||||
listMasonry = undefined;
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.initMasonry();
|
this.scrollHandlerWrapper = this.scrollHandler.bind(this);
|
||||||
|
this.setColumnCountWrapper = this.setColumnCount.bind(this);
|
||||||
|
this.setColumnCount();
|
||||||
|
|
||||||
this.$refs.list.onscroll = () => {
|
this.$refs.list.addEventListener('scroll', this.scrollHandlerWrapper);
|
||||||
const currentPage = Math.floor(this.issues.length / this.perPage);
|
window.addEventListener('resize', this.setColumnCountWrapper);
|
||||||
|
|
||||||
if ((this.scrollTop() > this.scrollHeight() - 100) && !this.loadingNewPage
|
|
||||||
&& currentPage === this.page) {
|
|
||||||
this.loadingNewPage = true;
|
|
||||||
this.page += 1;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
},
|
},
|
||||||
destroyed() {
|
beforeDestroy() {
|
||||||
this.destroyMasonry();
|
this.$refs.list.removeEventListener('scroll', this.scrollHandlerWrapper);
|
||||||
|
window.removeEventListener('resize', this.setColumnCountWrapper);
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
'issue-card-inner': gl.issueBoards.IssueCardInner,
|
'issue-card-inner': gl.issueBoards.IssueCardInner,
|
||||||
|
@ -108,25 +111,29 @@
|
||||||
class="add-issues-list add-issues-list-columns"
|
class="add-issues-list add-issues-list-columns"
|
||||||
ref="list">
|
ref="list">
|
||||||
<div
|
<div
|
||||||
v-for="issue in loopIssues"
|
v-for="group in groupedIssues"
|
||||||
v-if="showIssue(issue)"
|
class="add-issues-list-column">
|
||||||
class="card-parent">
|
|
||||||
<div
|
<div
|
||||||
class="card"
|
v-for="issue in group"
|
||||||
:class="{ 'is-active': issue.selected }"
|
v-if="showIssue(issue)"
|
||||||
@click="toggleIssue($event, issue)">
|
class="card-parent">
|
||||||
<issue-card-inner
|
<div
|
||||||
:issue="issue"
|
class="card"
|
||||||
:issue-link-base="issueLinkBase"
|
:class="{ 'is-active': issue.selected }"
|
||||||
:root-path="rootPath">
|
@click="toggleIssue($event, issue)">
|
||||||
</issue-card-inner>
|
<issue-card-inner
|
||||||
<span
|
:issue="issue"
|
||||||
:aria-label="'Issue #' + issue.id + ' selected'"
|
:issue-link-base="issueLinkBase"
|
||||||
aria-checked="true"
|
:root-path="rootPath">
|
||||||
v-if="issue.selected"
|
</issue-card-inner>
|
||||||
class="issue-card-selected text-center">
|
<span
|
||||||
<i class="fa fa-check"></i>
|
:aria-label="'Issue #' + issue.id + ' selected'"
|
||||||
</span>
|
aria-checked="true"
|
||||||
|
v-if="issue.selected"
|
||||||
|
class="issue-card-selected text-center">
|
||||||
|
<i class="fa fa-check"></i>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
href="#"
|
href="#"
|
||||||
role="button"
|
role="button"
|
||||||
:class="{ 'is-active': list.id == selected.id }"
|
:class="{ 'is-active': list.id == selected.id }"
|
||||||
@click="modal.selectedList = list">
|
@click.prevent="modal.selectedList = list">
|
||||||
<span
|
<span
|
||||||
class="dropdown-label-box"
|
class="dropdown-label-box"
|
||||||
:style="{ backgroundColor: list.label.color }">
|
:style="{ backgroundColor: list.label.color }">
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
href="#"
|
href="#"
|
||||||
role="button"
|
role="button"
|
||||||
@click.prevent="changeTab('all')">
|
@click.prevent="changeTab('all')">
|
||||||
<span>All issues</span>
|
All issues
|
||||||
<span class="badge">
|
<span class="badge">
|
||||||
{{ issuesCount }}
|
{{ issuesCount }}
|
||||||
</span>
|
</span>
|
||||||
|
@ -34,7 +34,7 @@
|
||||||
href="#"
|
href="#"
|
||||||
role="button"
|
role="button"
|
||||||
@click.prevent="changeTab('selected')">
|
@click.prevent="changeTab('selected')">
|
||||||
<span>Selected issues</span>
|
Selected issues
|
||||||
<span class="badge">
|
<span class="badge">
|
||||||
{{ selectedCount }}
|
{{ selectedCount }}
|
||||||
</span>
|
</span>
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
|
/* eslint-disable no-new */
|
||||||
/* global Vue */
|
/* global Vue */
|
||||||
|
/* global Flash */
|
||||||
(() => {
|
(() => {
|
||||||
const Store = gl.issueBoards.BoardsStore;
|
const Store = gl.issueBoards.BoardsStore;
|
||||||
|
|
||||||
|
@ -18,17 +20,24 @@
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
removeIssue() {
|
removeIssue() {
|
||||||
const lists = this.issue.getLists();
|
const issue = this.issue;
|
||||||
|
const lists = issue.getLists();
|
||||||
const labelIds = lists.map(list => list.label.id);
|
const labelIds = lists.map(list => list.label.id);
|
||||||
|
|
||||||
// Post the remove data
|
// Post the remove data
|
||||||
gl.boardService.bulkUpdate([this.issue.globalId], {
|
gl.boardService.bulkUpdate([issue.globalId], {
|
||||||
remove_label_ids: labelIds,
|
remove_label_ids: labelIds,
|
||||||
|
}).catch(() => {
|
||||||
|
new Flash('Failed to remove issue from board, please try again.', 'alert');
|
||||||
|
|
||||||
|
lists.forEach((list) => {
|
||||||
|
list.addIssue(issue);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Remove from the frontend store
|
// Remove from the frontend store
|
||||||
lists.forEach((list) => {
|
lists.forEach((list) => {
|
||||||
list.removeIssue(this.issue);
|
list.removeIssue(issue);
|
||||||
});
|
});
|
||||||
|
|
||||||
Store.detail.issue = {};
|
Store.detail.issue = {};
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
class ModalStore {
|
class ModalStore {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.store = {
|
this.store = {
|
||||||
|
columns: 3,
|
||||||
issues: [],
|
issues: [],
|
||||||
issuesCount: false,
|
issuesCount: false,
|
||||||
selectedIssues: [],
|
selectedIssues: [],
|
||||||
|
@ -25,9 +26,11 @@
|
||||||
|
|
||||||
toggleIssue(issueObj) {
|
toggleIssue(issueObj) {
|
||||||
const issue = issueObj;
|
const issue = issueObj;
|
||||||
issue.selected = !issue.selected;
|
const selected = issue.selected;
|
||||||
|
|
||||||
if (issue.selected) {
|
issue.selected = !selected;
|
||||||
|
|
||||||
|
if (!selected) {
|
||||||
this.addSelectedIssue(issue);
|
this.addSelectedIssue(issue);
|
||||||
} else {
|
} else {
|
||||||
this.removeSelectedIssue(issue);
|
this.removeSelectedIssue(issue);
|
||||||
|
|
|
@ -161,6 +161,9 @@
|
||||||
gl.text.humanize = function(string) {
|
gl.text.humanize = function(string) {
|
||||||
return string.charAt(0).toUpperCase() + string.replace(/_/g, ' ').slice(1);
|
return string.charAt(0).toUpperCase() + string.replace(/_/g, ' ').slice(1);
|
||||||
};
|
};
|
||||||
|
gl.text.pluralize = function(str, count) {
|
||||||
|
return str + (count > 1 || count === 0 ? 's' : '');
|
||||||
|
};
|
||||||
return gl.text.truncate = function(string, maxLength) {
|
return gl.text.truncate = function(string, maxLength) {
|
||||||
return string.substr(0, (maxLength - 3)) + '...';
|
return string.substr(0, (maxLength - 3)) + '...';
|
||||||
};
|
};
|
||||||
|
|
|
@ -418,6 +418,18 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.add-issues-list-column {
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
@media (min-width: $screen-sm-min) {
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: $screen-md-min) {
|
||||||
|
width: (100% / 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.add-issues-list {
|
.add-issues-list {
|
||||||
display: -webkit-flex;
|
display: -webkit-flex;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -429,16 +441,7 @@
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
|
|
||||||
.card-parent {
|
.card-parent {
|
||||||
width: 100%;
|
|
||||||
padding: 0 5px 5px;
|
padding: 0 5px 5px;
|
||||||
|
|
||||||
@media (min-width: $screen-sm-min) {
|
|
||||||
width: 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: $screen-md-min) {
|
|
||||||
width: (100% / 3);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.card {
|
.card {
|
||||||
|
@ -480,6 +483,6 @@
|
||||||
color: $white-light;
|
color: $white-light;
|
||||||
border: 1px solid $border-blue-light;
|
border: 1px solid $border-blue-light;
|
||||||
font-size: 9px;
|
font-size: 9px;
|
||||||
line-height: 17px;
|
line-height: 15px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ describe('Issue model', () => {
|
||||||
let issue;
|
let issue;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
gl.boardService = new BoardService('/test/issue-boards/board', '1');
|
gl.boardService = new BoardService('/test/issue-boards/board', '', '1');
|
||||||
gl.issueBoards.BoardsStore.create();
|
gl.issueBoards.BoardsStore.create();
|
||||||
|
|
||||||
issue = new ListIssue({
|
issue = new ListIssue({
|
||||||
|
|
|
@ -24,7 +24,7 @@ describe('List model', () => {
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
Vue.http.interceptors.push(boardsMockInterceptor);
|
Vue.http.interceptors.push(boardsMockInterceptor);
|
||||||
gl.boardService = new BoardService('/test/issue-boards/board', '1');
|
gl.boardService = new BoardService('/test/issue-boards/board', '', '1');
|
||||||
gl.issueBoards.BoardsStore.create();
|
gl.issueBoards.BoardsStore.create();
|
||||||
|
|
||||||
list = new List(listObj);
|
list = new List(listObj);
|
||||||
|
|
|
@ -21,5 +21,19 @@
|
||||||
expect(largeFont > regular).toBe(true);
|
expect(largeFont > regular).toBe(true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('gl.text.pluralize', () => {
|
||||||
|
it('returns pluralized', () => {
|
||||||
|
expect(gl.text.pluralize('test', 2)).toBe('tests');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns pluralized', () => {
|
||||||
|
expect(gl.text.pluralize('test', 0)).toBe('tests');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not return pluralized', () => {
|
||||||
|
expect(gl.text.pluralize('test', 1)).toBe('test');
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
|
|
2463
vendor/assets/javascripts/masonry.js
vendored
2463
vendor/assets/javascripts/masonry.js
vendored
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue