diff options
10 files changed, 198 insertions, 77 deletions
diff --git a/app/assets/javascripts/boards/components/modal/filters.js.es6 b/app/assets/javascripts/boards/components/modal/filters.js.es6 index 206948b70f4..c6c22dd24c9 100644 --- a/app/assets/javascripts/boards/components/modal/filters.js.es6 +++ b/app/assets/javascripts/boards/components/modal/filters.js.es6 @@ -1,15 +1,19 @@ /* global Vue */ -/* global MilestoneSelect */ //= require_tree ./filters (() => { const ModalStore = gl.issueBoards.ModalStore; gl.issueBoards.ModalFilters = Vue.extend({ - mounted() { - new MilestoneSelect(); + props: { + projectId: { + type: Number, + required: true, + }, }, components: { 'user-filter': gl.issueBoards.ModalFilterUser, + 'milestone-filter': gl.issueBoards.ModalFilterMilestone, + 'label-filter': gl.issueBoards.ModalLabelFilter, }, template: ` <div class="modal-filters"> @@ -17,58 +21,17 @@ dropdown-class-name="dropdown-menu-author" toggle-class-name="js-user-search js-author-search" toggle-label="Author" - field-name="author_id"></user-filter> + 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"></user-filter> - <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-project-id="12" - :data-milestones="'/root/test/milestones.json'"> - Milestone - <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> - <div class="dropdown"> - <button - class="dropdown-menu-toggle js-label-select js-multiselect" - type="button" - data-toggle="dropdown"> - Label - <i class="fa fa-chevron-down"></i> - </button> - </div> + :null-user="true" + :project-id="projectId"></user-filter> + <milestone-filter></milestone-filter> + <label-filter></label-filter> </div> `, }); diff --git a/app/assets/javascripts/boards/components/modal/filters/label.js.es6 b/app/assets/javascripts/boards/components/modal/filters/label.js.es6 new file mode 100644 index 00000000000..cfea0780983 --- /dev/null +++ b/app/assets/javascripts/boards/components/modal/filters/label.js.es6 @@ -0,0 +1,48 @@ +/* global Vue */ +/* global LabelSelect */ +(() => { + gl.issueBoards.ModalLabelFilter = Vue.extend({ + 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-labels="/root/test/labels.json" + data-show-any="true" + data-show-no="true" + 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.es6 b/app/assets/javascripts/boards/components/modal/filters/milestone.js.es6 new file mode 100644 index 00000000000..14c95cb2dae --- /dev/null +++ b/app/assets/javascripts/boards/components/modal/filters/milestone.js.es6 @@ -0,0 +1,49 @@ +/* global Vue */ +/* global MilestoneSelect */ +(() => { + gl.issueBoards.ModalFilterMilestone = Vue.extend({ + 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="'/root/test/milestones.json'" + 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.es6 b/app/assets/javascripts/boards/components/modal/filters/user.js.es6 index b440abf84e9..d45649af4cd 100644 --- a/app/assets/javascripts/boards/components/modal/filters/user.js.es6 +++ b/app/assets/javascripts/boards/components/modal/filters/user.js.es6 @@ -25,9 +25,13 @@ required: false, default: false, }, + projectId: { + type: Number, + required: true, + }, }, mounted() { - new UsersSelect(); + new UsersSelect(null, this.$refs.dropdown); }, computed: { currentUsername() { @@ -51,9 +55,12 @@ :data-any-user="'Any ' + toggleLabel" :data-null-user="nullUser" :data-field-name="fieldName" - :data-project-id="12" - :data-first-user="currentUsername"> - {{ toggleLabel }} + :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 diff --git a/app/assets/javascripts/boards/components/modal/header.js.es6 b/app/assets/javascripts/boards/components/modal/header.js.es6 index 87c407f5fec..cd672e0f1b2 100644 --- a/app/assets/javascripts/boards/components/modal/header.js.es6 +++ b/app/assets/javascripts/boards/components/modal/header.js.es6 @@ -6,6 +6,12 @@ gl.issueBoards.ModalHeader = Vue.extend({ mixins: [gl.issueBoards.ModalMixins], + props: { + projectId: { + type: Number, + required: true, + }, + }, data() { return ModalStore.store; }, @@ -30,6 +36,7 @@ }, components: { 'modal-tabs': gl.issueBoards.ModalTabs, + 'modal-filters': gl.issueBoards.ModalFilters, }, template: ` <div> @@ -50,7 +57,9 @@ <div class="add-issues-search append-bottom-10" v-if="showSearch"> - <modal-filters></modal-filters> + <modal-filters + :project-id="projectId"> + </modal-filters> <input placeholder="Search issues..." class="form-control" diff --git a/app/assets/javascripts/boards/components/modal/index.js.es6 b/app/assets/javascripts/boards/components/modal/index.js.es6 index 5bcbd2668af..49f4c73151e 100644 --- a/app/assets/javascripts/boards/components/modal/index.js.es6 +++ b/app/assets/javascripts/boards/components/modal/index.js.es6 @@ -25,6 +25,10 @@ type: String, required: true, }, + projectId: { + type: Number, + required: true, + }, }, data() { return ModalStore.store; @@ -52,8 +56,7 @@ }, filter: { handler() { - this.issues = []; - this.loadIssues(); + this.loadIssues(true); }, deep: true, } @@ -119,7 +122,9 @@ class="add-issues-modal" v-if="showAddIssuesModal"> <div class="add-issues-container"> - <modal-header></modal-header> + <modal-header + :project-id="projectId"> + </modal-header> <modal-list :issue-link-base="issueLinkBase" :root-path="rootPath" diff --git a/app/assets/javascripts/boards/stores/modal_store.js.es6 b/app/assets/javascripts/boards/stores/modal_store.js.es6 index 95b0b3f9484..ed42af301cd 100644 --- a/app/assets/javascripts/boards/stores/modal_store.js.es6 +++ b/app/assets/javascripts/boards/stores/modal_store.js.es6 @@ -21,6 +21,7 @@ author_id: '', assignee_id: '', milestone_title: '', + label_name: [], }, }; } diff --git a/app/assets/javascripts/labels_select.js b/app/assets/javascripts/labels_select.js index 70dc0d06b7b..e4cf9057e6d 100644 --- a/app/assets/javascripts/labels_select.js +++ b/app/assets/javascripts/labels_select.js @@ -4,10 +4,17 @@ (function() { this.LabelsSelect = (function() { - function LabelsSelect() { - var _this; + function LabelsSelect(els) { + var _this, $els; _this = this; - $('.js-label-select').each(function(i, dropdown) { + + $els = $(els); + + if (!els) { + $els = $('.js-label-select'); + } + + $els.each(function(i, dropdown) { var $block, $colorPreview, $dropdown, $form, $loading, $selectbox, $sidebarCollapsedValue, $value, abilityName, defaultLabel, enableLabelCreateButton, issueURLSplit, issueUpdateURL, labelHTMLTemplate, labelNoneHTMLTemplate, labelUrl, namespacePath, projectPath, saveLabelData, selectedLabel, showAny, showNo, $sidebarLabelTooltip, initialSelected, $toggleText, fieldName, useId, propertyName, showMenuAbove, $container, $dropdownContainer; $dropdown = $(dropdown); $dropdownContainer = $dropdown.closest('.labels-filter'); @@ -324,7 +331,7 @@ multiSelect: $dropdown.hasClass('js-multiselect'), vue: $dropdown.hasClass('js-issue-board-sidebar'), clicked: function(label, $el, e, isMarking) { - var isIssueIndex, isMRIndex, page; + var isIssueIndex, isMRIndex, page, boardsModel; page = $('body').data('page'); isIssueIndex = page === 'projects:issues:index'; @@ -346,22 +353,31 @@ return; } - if ($('html').hasClass('issue-boards-page') && !$dropdown.hasClass('js-issue-board-sidebar')) { + if ($('html').hasClass('issue-boards-page') && !$dropdown.hasClass('js-issue-board-sidebar') && + !$dropdown.closest('.add-issues-modal').length) { + boardsModel = gl.issueBoards.BoardsStore.state.filters; + } else if ($dropdown.closest('.add-issues-modal').length) { + boardsModel = gl.issueBoards.ModalStore.store.filter; + } + + if (boardsModel) { if (label.isAny) { - gl.issueBoards.BoardsStore.state.filters['label_name'] = []; + boardsModel['label_name'] = []; } else if ($el.hasClass('is-active')) { - gl.issueBoards.BoardsStore.state.filters['label_name'].push(label.title); + boardsModel['label_name'].push(label.title); } else { - var filters = gl.issueBoards.BoardsStore.state.filters['label_name']; + var filters = boardsModel['label_name']; filters = filters.filter(function (filteredLabel) { return filteredLabel !== label.title; }); - gl.issueBoards.BoardsStore.state.filters['label_name'] = filters; + boardsModel['label_name'] = filters; } - gl.issueBoards.BoardsStore.updateFiltersUrl(); + if (!$dropdown.closest('.add-issues-modal').length) { + gl.issueBoards.BoardsStore.updateFiltersUrl(); + } e.preventDefault(); return; } diff --git a/app/assets/javascripts/milestone_select.js b/app/assets/javascripts/milestone_select.js index f7e1f4a0816..a026f178720 100644 --- a/app/assets/javascripts/milestone_select.js +++ b/app/assets/javascripts/milestone_select.js @@ -5,12 +5,19 @@ (function() { this.MilestoneSelect = (function() { - function MilestoneSelect(currentProject) { + function MilestoneSelect(currentProject, els) { var _this; if (currentProject != null) { _this = this; this.currentProject = JSON.parse(currentProject); } + + $els = $(els); + + if (!els) { + $els = $('.js-label-select'); + } + $('.js-milestone-select').each(function(i, dropdown) { var $block, $dropdown, $loading, $selectbox, $sidebarCollapsedValue, $value, abilityName, collapsedSidebarLabelTemplate, defaultLabel, issuableId, issueUpdateURL, milestoneLinkNoneTemplate, milestoneLinkTemplate, milestonesUrl, projectId, selectedMilestone, showAny, showNo, showUpcoming, useId, showMenuAbove; $dropdown = $(dropdown); @@ -108,7 +115,7 @@ }, vue: $dropdown.hasClass('js-issue-board-sidebar'), clicked: function(selected, $el, e) { - var data, isIssueIndex, isMRIndex, page; + var data, isIssueIndex, isMRIndex, page, boardsStore; page = $('body').data('page'); isIssueIndex = page === 'projects:issues:index'; isMRIndex = (page === page && page === 'projects:merge_requests:index'); @@ -116,11 +123,19 @@ e.preventDefault(); return; } - if ($el.closest('.add-issues-modal').length) { - gl.issueBoards.ModalStore.store.filter[$dropdown.data('field-name')] = selected.name; - } else if ($('html').hasClass('issue-boards-page') && !$dropdown.hasClass('js-issue-board-sidebar')) { - gl.issueBoards.BoardsStore.state.filters[$dropdown.data('field-name')] = selected.name; - gl.issueBoards.BoardsStore.updateFiltersUrl(); + + if ($('html').hasClass('issue-boards-page') && !$dropdown.hasClass('js-issue-board-sidebar') && + !$dropdown.closest('.add-issues-modal').length) { + boardsStore = gl.issueBoards.BoardsStore.state.filters; + } else if ($dropdown.closest('.add-issues-modal').length) { + boardsStore = gl.issueBoards.ModalStore.store.filter; + } + + if (boardsStore) { + boardsStore[$dropdown.data('field-name')] = selected.name; + if (!$dropdown.closest('.add-issues-modal').length) { + gl.issueBoards.BoardsStore.updateFiltersUrl(); + } e.preventDefault(); } else if ($dropdown.hasClass('js-filter-submit') && (isIssueIndex || isMRIndex)) { if (selected.name != null) { diff --git a/app/assets/javascripts/users_select.js b/app/assets/javascripts/users_select.js index 8ad0aa7aee8..07458bed2e6 100644 --- a/app/assets/javascripts/users_select.js +++ b/app/assets/javascripts/users_select.js @@ -8,7 +8,8 @@ slice = [].slice; this.UsersSelect = (function() { - function UsersSelect(currentUser) { + function UsersSelect(currentUser, els) { + var $els; this.users = bind(this.users, this); this.user = bind(this.user, this); this.usersPath = "/autocomplete/users.json"; @@ -20,7 +21,14 @@ this.currentUser = JSON.parse(currentUser); } } - $('.js-user-search').each((function(_this) { + + $els = $(els); + + if (!els) { + $els = $('.js-label-select'); + } + + $els.each((function(_this) { return function(i, dropdown) { var options = {}; var $block, $collapsedSidebar, $dropdown, $loading, $selectbox, $value, abilityName, assignTo, assigneeTemplate, collapsedAssigneeTemplate, defaultLabel, firstUser, issueURL, selectedId, showAnyUser, showNullUser, showMenuAbove; |