Commit 6ad9a66b authored by Simon Knox's avatar Simon Knox

add weight select dropdown

parent d867b9a7
......@@ -52,9 +52,6 @@
<!-- TODO: if current_board_parent.issue_board_milestone_available?(current_user) -->
<form-block
title="Milestone"
defaultText="Any milestone"
:canEdit="canAdminBoard"
>
<div
v-if="board.milestone"
......@@ -65,8 +62,11 @@
<board-milestone-select
:board="board"
:milestone-path="milestonePath"
v-model="board.milestone_id">
</board-milestone-select>
v-model="board.milestone_id"
title="Milestone"
defaultText="Any milestone"
:canEdit="canAdminBoard"
/>
</form-block>
<form-block
......@@ -98,6 +98,13 @@
:fieldName="'board_filter[weight]'"
:canEdit="canAdminBoard"
>
<board-weight-select
:board="board"
v-model="board.weight"
title="Weight"
defaultText="Any weight"
:canEdit="canAdminBoard"
/>
</form-block>
</div>
</form>
......@@ -115,6 +122,7 @@ import Vue from 'vue';
import PopupDialog from '~/vue_shared/components/popup_dialog.vue';
import FormBlock from './form_block.vue';
import BoardMilestoneSelect from './milestone_select.vue';
import BoardWeightSelect from './weight_select.vue';
window.gl = window.gl || {};
window.gl.issueBoards = window.gl.issueBoards || {};
......@@ -148,6 +156,7 @@ export default Vue.extend({
},
components: {
BoardMilestoneSelect,
BoardWeightSelect,
PopupDialog,
FormBlock,
},
......
<template>
<div class="list-item">
<div class="media">
<label class="label-light media-body">{{ title }}</label>
<a
v-if="canEdit"
class="edit-link"
href="#"
@click.prevent="toggleEditing"
>
Edit
</a>
</div>
<slot></slot>
<div>
<slot name="currentValue">
{{ defaultText }}
</slot>
</div>
</div>
</template>
......@@ -25,23 +9,6 @@ import eventHub from '../eventhub';
export default {
props: {
defaultText: {
type: String,
required: true,
},
title: {
type: String,
required: true,
},
fieldName: {
type: String,
required: false,
},
canEdit: {
type: Boolean,
required: false,
default: false,
},
},
data() {
return {
......
<template>
<div class="dropdown" :class="{ open: isOpen }">
<div class="media">
<label class="label-light media-body">{{ title }}</label>
<a
v-if="canEdit"
class="edit-link"
href="#"
@click.prevent="toggle"
>
Edit
</a>
</div>
<div
class="dropdown-menu dropdown-menu-wide"
>
<div class="dropdown-input">
<input
ref="search"
class="dropdown-input-field"
type="search"
placeholder="Search milestones">
<i aria-hidden="true" data-hidden="true" class="fa fa-search dropdown-input-search"></i>
</div>
<ul
ref="list"
>
......@@ -47,6 +50,9 @@
</li>
</ul>
</div>
<div>
{{ milestoneTitle }}
</div>
</div>
</template>
......@@ -71,10 +77,28 @@ export default {
type: Number,
required: false,
},
defaultText: {
type: String,
required: true,
},
title: {
type: String,
required: true,
},
canEdit: {
type: Boolean,
required: false,
default: false,
},
},
components: {
loadingIcon,
},
computed: {
milestoneTitle() {
return this.board.milestone ? this.board.milestone.title : this.defaultText;
},
},
data() {
return {
isOpen: false,
......@@ -96,9 +120,6 @@ export default {
eventHub.$on('open', this.open);
eventHub.$on('close', this.close);
eventHub.$on('toggle', this.toggle);
this.$nextTick(() => {
this.$refs.search.focus();
});
},
beforeDestroy() {
eventHub.$off('open', this.open);
......
<template>
<div class="dropdown" :class="{ open: isOpen }">
<div class="media">
<label class="label-light media-body">{{ title }}</label>
<a
v-if="canEdit"
class="edit-link"
href="#"
@click.prevent="toggle"
>
Edit
</a>
</div>
<div
class="dropdown-menu dropdown-menu-wide"
>
<ul
ref="list"
>
<li>
<a
href="#"
@click.prevent.stop="selectWeight(0)"
>
<i
class="fa fa-check"
v-if="0 === value"></i>
No weight
</a>
</li>
<li
v-for="weight in weights"
:key="weight.id"
>
<a
href="#"
@click.prevent.stop="selectWeight(weight)">
<i
class="fa fa-check"
v-if="weight === value"></i>
{{ weight }}
</a>
</li>
</ul>
</div>
<div>
{{ weight }}
</div>
</div>
</template>
<script>
/* global BoardService */
import loadingIcon from '~/vue_shared/components/loading_icon.vue';
import eventHub from '../eventhub';
export default {
props: {
board: {
type: Object,
required: true,
},
value: {
type: Number,
required: false,
},
defaultText: {
type: String,
required: true,
},
title: {
type: String,
required: true,
},
canEdit: {
type: Boolean,
required: false,
default: false,
},
},
components: {
loadingIcon,
},
computed: {
weight() {
if (parseInt(this.board.weight, 10) === 0) {
return 'No weight';
}
return this.board.weight || 'Any weight';
},
},
data() {
return {
isOpen: false,
// TODO: use Issue.weight_options from backend
weights: [1, 2, 3, 4, 5, 6, 7, 8, 9],
};
},
methods: {
selectWeight(weight) {
this.$set(this.board, 'weight', weight);
// this.$emit('input', weight);
this.close();
},
open() {
this.isOpen = true;
},
close() {
this.isOpen = false;
},
toggle() {
this.isOpen = !this.isOpen;
},
},
};
</script>
require 'rails_helper'
describe 'Board with milestone', :js do
let(:user) { create(:user) }
let(:project) { create(:project, :public) }
let!(:milestone) { create(:milestone, project: project) }
let!(:issue) { create(:closed_issue, project: project) }
let!(:issue_milestone) { create(:closed_issue, project: project, milestone: milestone) }
before do
allow_any_instance_of(ApplicationHelper).to receive(:collapsed_sidebar?).and_return(true)
project.team << [user, :master]
sign_in(user)
end
context 'with the feature enabled' do
before do
stub_licensed_features(issue_board_milestone: true)
end
context 'new board' do
before do
visit project_boards_path(project)
end
it 'creates board with milestone' do
create_board_with_milestone
expect(find('.tokens-container')).to have_content(milestone.title)
wait_for_requests
find('.card', match: :first)
expect(all('.board').last).to have_selector('.card', count: 1)
end
end
context 'update board' do
let!(:milestone_two) { create(:milestone, project: project) }
let!(:board) { create(:board, project: project, milestone: milestone) }
before do
visit project_boards_path(project)
end
it 'defaults milestone filter' do
page.within '#js-multiple-boards-switcher' do
find('.dropdown-menu-toggle').click
wait_for_requests
click_link board.name
end
expect(find('.tokens-container')).to have_content(milestone.title)
find('.card', match: :first)
expect(all('.board').last).to have_selector('.card', count: 1)
end
it 'sets board to any milestone' do
update_board_milestone('Any Milestone')
expect(page).not_to have_css('.js-visual-token')
expect(find('.tokens-container')).not_to have_content(milestone.title)
find('.card', match: :first)
expect(page).to have_selector('.board', count: 3)
expect(all('.board').last).to have_selector('.card', count: 2)
end
it 'sets board to upcoming milestone' do
update_board_milestone('Upcoming')
expect(find('.tokens-container')).not_to have_content(milestone.title)
find('.board', match: :first)
expect(all('.board')[1]).to have_selector('.card', count: 0)
end
it 'does not allow milestone in filter to be editted' do
find('.filtered-search').native.send_keys(:backspace)
page.within('.tokens-container') do
expect(page).to have_selector('.value')
end
end
it 'does not render milestone in hint dropdown' do
find('.filtered-search').click
page.within('#js-dropdown-hint') do
expect(page).not_to have_button('Milestone')
end
end
end
context 'removing issue from board' do
let(:label) { create(:label, project: project) }
let!(:issue) { create(:labeled_issue, project: project, labels: [label], milestone: milestone) }
let!(:board) { create(:board, project: project, milestone: milestone) }
let!(:list) { create(:list, board: board, label: label, position: 0) }
before do
visit project_boards_path(project)
end
it 'removes issues milestone when removing from the board' do
wait_for_requests
first('.card .card-number').click
click_button('Remove from board')
wait_for_requests
expect(issue.reload.milestone).to be_nil
end
end
context 'new issues' do
let(:label) { create(:label, project: project) }
let!(:list1) { create(:list, board: board, label: label, position: 0) }
let!(:board) { create(:board, project: project, milestone: milestone) }
let!(:issue) { create(:issue, project: project) }
before do
visit project_boards_path(project)
end
it 'creates new issue with boards milestone' do
wait_for_requests
page.within(first('.board')) do
find('.btn-default').click
find('.form-control').set('testing new issue with milestone')
click_button('Submit issue')
wait_for_requests
click_link('testing new issue with milestone')
end
expect(page).to have_content(milestone.title)
end
it 'updates issue with milestone from add issues modal' do
wait_for_requests
click_button 'Add issues'
page.within('.add-issues-modal') do
card = find('.card', :first)
expect(page).to have_selector('.card', count: 1)
card.click
click_button 'Add 1 issue'
end
click_link(issue.title)
expect(page).to have_content(milestone.title)
end
end
end
context 'with the feature disabled' do
before do
stub_licensed_features(issue_board_milestone: false)
visit project_boards_path(project)
end
it "doesn't show the input when creating a board" do
page.within '#js-multiple-boards-switcher' do
find('.dropdown-menu-toggle').click
click_link 'Create new board'
# To make sure the form is shown
expect(page).to have_selector('#board-new-name')
expect(page).not_to have_button('Milestone')
end
end
it "doesn't show the option to edit the milestone" do
page.within '#js-multiple-boards-switcher' do
find('.dropdown-menu-toggle').click
# To make sure the dropdown is open
expect(page).to have_link('Edit board name')
expect(page).not_to have_link('Edit board milestone')
end
end
end
def create_board_with_milestone
page.within '#js-multiple-boards-switcher' do
find('.dropdown-menu-toggle').click
click_link 'Create new board'
find('#board-new-name').set 'test'
find('button', text: 'Any Milestone').trigger('click')
find('a', text: milestone.title).trigger('click')
click_button 'Create'
end
end
def update_board_milestone(milestone_title)
page.within '#js-multiple-boards-switcher' do
find('.dropdown-menu-toggle').click
click_link 'Edit board milestone'
click_link milestone_title
click_button 'Save'
end
end
end
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