summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/boards/components
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/boards/components')
-rw-r--r--app/assets/javascripts/boards/components/board.js5
-rw-r--r--app/assets/javascripts/boards/components/board_blank_state.js119
-rw-r--r--app/assets/javascripts/boards/components/modal/empty_state.js4
-rw-r--r--app/assets/javascripts/boards/components/modal/filters.js57
-rw-r--r--app/assets/javascripts/boards/components/modal/filters/label.js54
-rw-r--r--app/assets/javascripts/boards/components/modal/filters/milestone.js55
-rw-r--r--app/assets/javascripts/boards/components/modal/filters/user.js96
-rw-r--r--app/assets/javascripts/boards/components/modal/header.js16
-rw-r--r--app/assets/javascripts/boards/components/modal/index.js18
-rw-r--r--app/assets/javascripts/boards/components/modal/tabs.js2
10 files changed, 108 insertions, 318 deletions
diff --git a/app/assets/javascripts/boards/components/board.js b/app/assets/javascripts/boards/components/board.js
index 30d3be453be..67c0c419713 100644
--- a/app/assets/javascripts/boards/components/board.js
+++ b/app/assets/javascripts/boards/components/board.js
@@ -2,7 +2,8 @@
/* global Vue */
/* global Sortable */
-require('./board_blank_state');
+import boardBlankState from './board_blank_state';
+
require('./board_delete');
require('./board_list');
@@ -17,7 +18,7 @@ require('./board_list');
components: {
'board-list': gl.issueBoards.BoardList,
'board-delete': gl.issueBoards.BoardDelete,
- 'board-blank-state': gl.issueBoards.BoardBlankState
+ boardBlankState,
},
props: {
list: Object,
diff --git a/app/assets/javascripts/boards/components/board_blank_state.js b/app/assets/javascripts/boards/components/board_blank_state.js
index d76314c1892..52893d4642b 100644
--- a/app/assets/javascripts/boards/components/board_blank_state.js
+++ b/app/assets/javascripts/boards/components/board_blank_state.js
@@ -1,53 +1,84 @@
-/* eslint-disable space-before-function-paren, comma-dangle */
-/* global Vue */
/* global ListLabel */
+/* global Cookies */
+const Store = gl.issueBoards.BoardsStore;
-(() => {
- const Store = gl.issueBoards.BoardsStore;
+export default {
+ template: `
+ <div class="board-blank-state">
+ <p>
+ Add the following default lists to your Issue Board with one click:
+ </p>
+ <ul class="board-blank-state-list">
+ <li v-for="label in predefinedLabels">
+ <span
+ class="label-color"
+ :style="{ backgroundColor: label.color }">
+ </span>
+ {{ label.title }}
+ </li>
+ </ul>
+ <p>
+ Starting out with the default set of lists will get you right on the way to making the most of your board.
+ </p>
+ <button
+ class="btn btn-create btn-inverted btn-block"
+ type="button"
+ @click.stop="addDefaultLists">
+ Add default lists
+ </button>
+ <button
+ class="btn btn-default btn-block"
+ type="button"
+ @click.stop="clearBlankState">
+ Nevermind, I'll use my own
+ </button>
+ </div>
+ `,
+ data() {
+ return {
+ predefinedLabels: [
+ new ListLabel({ title: 'To Do', color: '#F0AD4E' }),
+ new ListLabel({ title: 'Doing', color: '#5CB85C' }),
+ ],
+ };
+ },
+ methods: {
+ addDefaultLists() {
+ this.clearBlankState();
- window.gl = window.gl || {};
- window.gl.issueBoards = window.gl.issueBoards || {};
-
- gl.issueBoards.BoardBlankState = Vue.extend({
- data () {
- return {
- predefinedLabels: [
- new ListLabel({ title: 'To Do', color: '#F0AD4E' }),
- new ListLabel({ title: 'Doing', color: '#5CB85C' })
- ]
- };
- },
- methods: {
- addDefaultLists () {
- this.clearBlankState();
-
- this.predefinedLabels.forEach((label, i) => {
- Store.addList({
+ this.predefinedLabels.forEach((label, i) => {
+ Store.addList({
+ title: label.title,
+ position: i,
+ list_type: 'label',
+ label: {
title: label.title,
- position: i,
- list_type: 'label',
- label: {
- title: label.title,
- color: label.color
- }
- });
+ color: label.color,
+ },
});
+ });
- Store.state.lists = _.sortBy(Store.state.lists, 'position');
+ Store.state.lists = _.sortBy(Store.state.lists, 'position');
- // Save the labels
- gl.boardService.generateDefaultLists()
- .then((resp) => {
- resp.json().forEach((listObj) => {
- const list = Store.findList('title', listObj.title);
+ // Save the labels
+ gl.boardService.generateDefaultLists()
+ .then((resp) => {
+ resp.json().forEach((listObj) => {
+ const list = Store.findList('title', listObj.title);
- list.id = listObj.id;
- list.label.id = listObj.label.id;
- list.getIssues();
- });
+ list.id = listObj.id;
+ list.label.id = listObj.label.id;
+ list.getIssues();
});
- },
- clearBlankState: Store.removeBlankState.bind(Store)
- }
- });
-})();
+ })
+ .catch(() => {
+ Store.removeList(undefined, 'label');
+ Cookies.remove('issue_board_welcome_hidden', {
+ path: '',
+ });
+ Store.addBlankState();
+ });
+ },
+ clearBlankState: Store.removeBlankState.bind(Store),
+ },
+};
diff --git a/app/assets/javascripts/boards/components/modal/empty_state.js b/app/assets/javascripts/boards/components/modal/empty_state.js
index 9538f5b69e9..e6973c3fd59 100644
--- a/app/assets/javascripts/boards/components/modal/empty_state.js
+++ b/app/assets/javascripts/boards/components/modal/empty_state.js
@@ -30,7 +30,7 @@
if (this.activeTab === 'selected') {
obj.title = 'You haven\'t selected any issues yet';
obj.content = `
- Go back to <strong>All issues</strong> and select some issues
+ Go back to <strong>Open issues</strong> and select some issues
to add to your board.
`;
}
@@ -59,7 +59,7 @@
class="btn btn-default"
@click="changeTab('all')"
v-if="activeTab === 'selected'">
- All issues
+ Open issues
</button>
</div>
</div>
diff --git a/app/assets/javascripts/boards/components/modal/filters.js b/app/assets/javascripts/boards/components/modal/filters.js
index 6de06811d94..bd394a2318c 100644
--- a/app/assets/javascripts/boards/components/modal/filters.js
+++ b/app/assets/javascripts/boards/components/modal/filters.js
@@ -1,49 +1,24 @@
-/* global Vue */
-const userFilter = require('./filters/user');
-const milestoneFilter = require('./filters/milestone');
-const labelFilter = require('./filters/label');
+import FilteredSearchBoards from '../../filtered_search_boards';
+import FilteredSearchContainer from '../../../filtered_search/container';
-module.exports = Vue.extend({
+export default {
name: 'modal-filters',
props: {
- projectId: {
- type: Number,
- required: true,
- },
- milestonePath: {
- type: String,
- required: true,
- },
- labelPath: {
- type: String,
+ store: {
+ type: Object,
required: true,
},
},
- destroyed() {
- gl.issueBoards.ModalStore.setDefaultFilter();
+ mounted() {
+ FilteredSearchContainer.container = this.$el;
+
+ this.filteredSearch = new FilteredSearchBoards(this.store);
+ this.filteredSearch.removeTokens();
},
- components: {
- userFilter,
- milestoneFilter,
- labelFilter,
+ beforeDestroy() {
+ this.filteredSearch.cleanup();
+ FilteredSearchContainer.container = document;
+ this.store.path = '';
},
- template: `
- <div class="modal-filters">
- <user-filter
- dropdown-class-name="dropdown-menu-author"
- toggle-class-name="js-user-search js-author-search"
- toggle-label="Author"
- field-name="author_id"
- :project-id="projectId"></user-filter>
- <user-filter
- dropdown-class-name="dropdown-menu-author"
- toggle-class-name="js-assignee-search"
- toggle-label="Assignee"
- field-name="assignee_id"
- :null-user="true"
- :project-id="projectId"></user-filter>
- <milestone-filter :milestone-path="milestonePath"></milestone-filter>
- <label-filter :label-path="labelPath"></label-filter>
- </div>
- `,
-});
+ template: '#js-board-modal-filter',
+};
diff --git a/app/assets/javascripts/boards/components/modal/filters/label.js b/app/assets/javascripts/boards/components/modal/filters/label.js
deleted file mode 100644
index 4fc8f72a145..00000000000
--- a/app/assets/javascripts/boards/components/modal/filters/label.js
+++ /dev/null
@@ -1,54 +0,0 @@
-/* eslint-disable no-new */
-/* global Vue */
-/* global LabelsSelect */
-module.exports = Vue.extend({
- name: 'filter-label',
- props: {
- labelPath: {
- type: String,
- required: true,
- },
- },
- mounted() {
- new LabelsSelect(this.$refs.dropdown);
- },
- template: `
- <div class="dropdown">
- <button
- class="dropdown-menu-toggle js-label-select js-multiselect js-extra-options"
- type="button"
- data-toggle="dropdown"
- data-show-any="true"
- data-show-no="true"
- :data-labels="labelPath"
- ref="dropdown">
- <span class="dropdown-toggle-text">
- Label
- </span>
- <i class="fa fa-chevron-down"></i>
- </button>
- <div class="dropdown-menu dropdown-select dropdown-menu-paging dropdown-menu-labels dropdown-menu-selectable">
- <div class="dropdown-title">
- Filter by label
- <button
- class="dropdown-title-button dropdown-menu-close"
- aria-label="Close"
- type="button">
- <i class="fa fa-times dropdown-menu-close-icon"></i>
- </button>
- </div>
- <div class="dropdown-input">
- <input
- type="search"
- class="dropdown-input-field"
- placeholder="Search"
- autocomplete="off" />
- <i class="fa fa-search dropdown-input-search"></i>
- <i role="button" class="fa fa-times dropdown-input-clear js-dropdown-input-clear"></i>
- </div>
- <div class="dropdown-content"></div>
- <div class="dropdown-loading"><i class="fa fa-spinner fa-spin"></i></div>
- </div>
- </div>
- `,
-});
diff --git a/app/assets/javascripts/boards/components/modal/filters/milestone.js b/app/assets/javascripts/boards/components/modal/filters/milestone.js
deleted file mode 100644
index d555599d300..00000000000
--- a/app/assets/javascripts/boards/components/modal/filters/milestone.js
+++ /dev/null
@@ -1,55 +0,0 @@
-/* eslint-disable no-new */
-/* global Vue */
-/* global MilestoneSelect */
-module.exports = Vue.extend({
- name: 'filter-milestone',
- props: {
- milestonePath: {
- type: String,
- required: true,
- },
- },
- mounted() {
- new MilestoneSelect(null, this.$refs.dropdown);
- },
- template: `
- <div class="dropdown">
- <button
- class="dropdown-menu-toggle js-milestone-select"
- type="button"
- data-toggle="dropdown"
- data-show-any="true"
- data-show-upcoming="true"
- data-field-name="milestone_title"
- :data-milestones="milestonePath"
- ref="dropdown">
- <span class="dropdown-toggle-text">
- Milestone
- </span>
- <i class="fa fa-chevron-down"></i>
- </button>
- <div class="dropdown-menu dropdown-select dropdown-menu-selectable dropdown-menu-milestone">
- <div class="dropdown-title">
- <span>Filter by milestone</span>
- <button
- class="dropdown-title-button dropdown-menu-close"
- aria-label="Close"
- type="button">
- <i class="fa fa-times dropdown-menu-close-icon"></i>
- </button>
- </div>
- <div class="dropdown-input">
- <input
- type="search"
- class="dropdown-input-field"
- placeholder="Search milestones"
- autocomplete="off" />
- <i class="fa fa-search dropdown-input-search"></i>
- <i role="button" class="fa fa-times dropdown-input-clear js-dropdown-input-clear"></i>
- </div>
- <div class="dropdown-content"></div>
- <div class="dropdown-loading"><i class="fa fa-spinner fa-spin"></i></div>
- </div>
- </div>
- `,
-});
diff --git a/app/assets/javascripts/boards/components/modal/filters/user.js b/app/assets/javascripts/boards/components/modal/filters/user.js
deleted file mode 100644
index 8523028c29c..00000000000
--- a/app/assets/javascripts/boards/components/modal/filters/user.js
+++ /dev/null
@@ -1,96 +0,0 @@
-/* eslint-disable no-new */
-/* global Vue */
-/* global UsersSelect */
-module.exports = Vue.extend({
- name: 'filter-user',
- props: {
- toggleClassName: {
- type: String,
- required: true,
- },
- dropdownClassName: {
- type: String,
- required: false,
- default: '',
- },
- toggleLabel: {
- type: String,
- required: true,
- },
- fieldName: {
- type: String,
- required: true,
- },
- nullUser: {
- type: Boolean,
- required: false,
- default: false,
- },
- projectId: {
- type: Number,
- required: true,
- },
- },
- mounted() {
- new UsersSelect(null, this.$refs.dropdown);
- },
- computed: {
- currentUsername() {
- return gon.current_username;
- },
- dropdownTitle() {
- return `Filter by ${this.toggleLabel.toLowerCase()}`;
- },
- inputPlaceholder() {
- return `Search ${this.toggleLabel.toLowerCase()}`;
- },
- },
- template: `
- <div class="dropdown">
- <button
- class="dropdown-menu-toggle js-user-search"
- :class="toggleClassName"
- type="button"
- data-toggle="dropdown"
- data-current-user="true"
- :data-any-user="'Any ' + toggleLabel"
- :data-null-user="nullUser"
- :data-field-name="fieldName"
- :data-project-id="projectId"
- :data-first-user="currentUsername"
- ref="dropdown">
- <span class="dropdown-toggle-text">
- {{ toggleLabel }}
- </span>
- <i class="fa fa-chevron-down"></i>
- </button>
- <div
- class="dropdown-menu dropdown-select dropdown-menu-user dropdown-menu-selectable"
- :class="dropdownClassName">
- <div class="dropdown-title">
- {{ dropdownTitle }}
- <button
- class="dropdown-title-button dropdown-menu-close"
- aria-label="Close"
- type="button">
- <i class="fa fa-times dropdown-menu-close-icon"></i>
- </button>
- </div>
- <div class="dropdown-input">
- <input
- type="search"
- class="dropdown-input-field"
- autocomplete="off"
- :placeholder="inputPlaceholder" />
- <i class="fa fa-search dropdown-input-search"></i>
- <i
- role="button"
- class="fa fa-times dropdown-input-clear js-dropdown-input-clear">
- </i>
- </div>
- <div class="dropdown-content"></div>
- <div class="dropdown-loading"><i class="fa fa-spinner fa-spin"></i></div>
- </div>
- </div>
- `,
-});
diff --git a/app/assets/javascripts/boards/components/modal/header.js b/app/assets/javascripts/boards/components/modal/header.js
index 70c088f9054..116e29cd177 100644
--- a/app/assets/javascripts/boards/components/modal/header.js
+++ b/app/assets/javascripts/boards/components/modal/header.js
@@ -1,6 +1,7 @@
-/* global Vue */
+import Vue from 'vue';
+import modalFilters from './filters';
+
require('./tabs');
-const modalFilters = require('./filters');
(() => {
const ModalStore = gl.issueBoards.ModalStore;
@@ -66,16 +67,7 @@ const modalFilters = require('./filters');
<div
class="add-issues-search append-bottom-10"
v-if="showSearch">
- <modal-filters
- :project-id="projectId"
- :milestone-path="milestonePath"
- :label-path="labelPath">
- </modal-filters>
- <input
- placeholder="Search issues..."
- class="form-control"
- type="search"
- v-model="searchTerm" />
+ <modal-filters :store="filter" />
<button
type="button"
class="btn btn-success btn-inverted prepend-left-10"
diff --git a/app/assets/javascripts/boards/components/modal/index.js b/app/assets/javascripts/boards/components/modal/index.js
index f290cd13763..4240c97617d 100644
--- a/app/assets/javascripts/boards/components/modal/index.js
+++ b/app/assets/javascripts/boards/components/modal/index.js
@@ -1,5 +1,6 @@
/* global Vue */
/* global ListIssue */
+import queryData from '../../utils/query_data';
require('./header');
require('./list');
@@ -47,9 +48,6 @@ require('./empty_state');
page() {
this.loadIssues();
},
- searchTerm() {
- this.searchOperation();
- },
showAddIssuesModal() {
if (this.showAddIssuesModal && !this.issues.length) {
this.loading = true;
@@ -66,25 +64,20 @@ require('./empty_state');
},
filter: {
handler() {
+ this.page = 1;
this.loadIssues(true);
},
deep: true,
},
},
methods: {
- searchOperation: _.debounce(function searchOperationDebounce() {
- this.loadIssues(true);
- }, 500),
loadIssues(clearIssues = false) {
if (!this.showAddIssuesModal) return false;
- const queryData = Object.assign({}, this.filter, {
- search: this.searchTerm,
+ return gl.boardService.getBacklog(queryData(this.filter.path, {
page: this.page,
per: this.perPage,
- });
-
- return gl.boardService.getBacklog(queryData).then((res) => {
+ })).then((res) => {
const data = res.json();
if (clearIssues) {
@@ -123,6 +116,9 @@ require('./empty_state');
return this.activeTab === 'selected' && this.selectedIssues.length === 0;
},
},
+ created() {
+ this.page = 1;
+ },
components: {
'modal-header': gl.issueBoards.ModalHeader,
'modal-list': gl.issueBoards.ModalList,
diff --git a/app/assets/javascripts/boards/components/modal/tabs.js b/app/assets/javascripts/boards/components/modal/tabs.js
index e8cb43f3503..1cd6ca0ee88 100644
--- a/app/assets/javascripts/boards/components/modal/tabs.js
+++ b/app/assets/javascripts/boards/components/modal/tabs.js
@@ -23,7 +23,7 @@
href="#"
role="button"
@click.prevent="changeTab('all')">
- All issues
+ Open issues
<span class="badge">
{{ issuesCount }}
</span>