summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xapp/assets/javascripts/boards/test_utils/simulate_drag.js121
-rw-r--r--app/assets/stylesheets/pages/boards.scss28
-rw-r--r--app/views/projects/boards/index.html.haml1
-rw-r--r--config/application.rb1
-rw-r--r--spec/features/boards/boards_spec.rb71
5 files changed, 218 insertions, 4 deletions
diff --git a/app/assets/javascripts/boards/test_utils/simulate_drag.js b/app/assets/javascripts/boards/test_utils/simulate_drag.js
new file mode 100755
index 00000000000..92bc8ea73a8
--- /dev/null
+++ b/app/assets/javascripts/boards/test_utils/simulate_drag.js
@@ -0,0 +1,121 @@
+(function () {
+ 'use strict';
+
+ function simulateEvent(el, type, options) {
+ var event;
+ var ownerDocument = el.ownerDocument;
+
+ options = options || {};
+
+ if (/^mouse/.test(type)) {
+ event = ownerDocument.createEvent('MouseEvents');
+ event.initMouseEvent(type, true, true, ownerDocument.defaultView,
+ options.button, options.screenX, options.screenY, options.clientX, options.clientY,
+ options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, options.button, el);
+ } else {
+ event = ownerDocument.createEvent('CustomEvent');
+
+ event.initCustomEvent(type, true, true, ownerDocument.defaultView,
+ options.button, options.screenX, options.screenY, options.clientX, options.clientY,
+ options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, options.button, el);
+
+ event.dataTransfer = {
+ data: {},
+
+ setData: function (type, val) {
+ this.data[type] = val;
+ },
+
+ getData: function (type) {
+ return this.data[type];
+ }
+ };
+ }
+
+ if (el.dispatchEvent) {
+ el.dispatchEvent(event);
+ } else if (el.fireEvent) {
+ el.fireEvent('on' + type, event);
+ }
+
+ return event;
+ }
+
+ function getTraget(target) {
+ var el = typeof target.el === 'string' ? document.getElementById(target.el.substr(1)) : target.el;
+ var children = el.children;
+
+ return (
+ children[target.index] ||
+ children[target.index === 'first' ? 0 : -1] ||
+ children[target.index === 'last' ? children.length - 1 : -1]
+ );
+ }
+
+ function getRect(el) {
+ var rect = el.getBoundingClientRect();
+ var width = rect.right - rect.left;
+ var height = rect.bottom - rect.top;
+
+ return {
+ x: rect.left,
+ y: rect.top,
+ cx: rect.left + width / 2,
+ cy: rect.top + height / 2,
+ w: width,
+ h: height,
+ hw: width / 2,
+ wh: height / 2
+ };
+ }
+
+ function simulateDrag(options, callback) {
+ options.to.el = options.to.el || options.from.el;
+
+ var fromEl = getTraget(options.from);
+ var toEl = getTraget(options.to);
+ var scrollable = options.scrollable;
+
+ var fromRect = getRect(fromEl);
+ var toRect = getRect(toEl);
+
+ var startTime = new Date().getTime();
+ var duration = options.duration || 1000;
+ simulateEvent(fromEl, 'mousedown', {button: 0});
+ options.ontap && options.ontap();
+
+ requestAnimationFrame(function () {
+ options.ondragstart && options.ondragstart();
+ });
+
+ requestAnimationFrame(function loop() {
+ var progress = (new Date().getTime() - startTime) / duration;
+ var x = (fromRect.cx + (toRect.cx - fromRect.cx) * progress) - scrollable.scrollLeft;
+ var y = fromRect.cy + (toRect.cy - fromRect.cy) * progress;
+ var overEl = fromEl.ownerDocument.elementFromPoint(x, y);
+
+ simulateEvent(overEl, 'mousemove', {
+ clientX: x,
+ clientY: y
+ });
+
+ if (progress < 1) {
+ requestAnimationFrame(loop);
+ } else {
+ options.ondragend && options.ondragend();
+ simulateEvent(toEl, 'mouseup');
+ }
+ });
+
+ return {
+ target: fromEl,
+ fromList: fromEl.parentNode,
+ toList: toEl.parentNode
+ };
+ }
+
+
+ // Export
+ window.simulateEvent = simulateEvent;
+ window.simulateDrag = simulateDrag;
+})();
diff --git a/app/assets/stylesheets/pages/boards.scss b/app/assets/stylesheets/pages/boards.scss
index 491cb4e37de..f0aecd10248 100644
--- a/app/assets/stylesheets/pages/boards.scss
+++ b/app/assets/stylesheets/pages/boards.scss
@@ -23,18 +23,33 @@
}
.issue-boards-page {
+ .content-wrapper {
+ display: -webkit-flex;
+ display: flex;
+ }
+
+ .sub-nav,
+ .issues-filters {
+ -webkit-flex: none;
+ flex: none;
+ }
+
.page-with-sidebar {
+ display: -webkit-flex;
display: flex;
min-height: 100vh;
max-height: 100vh;
}
.issue-boards-content {
+ display: -webkit-flex;
display: flex;
- height: 100%;
+ width: 100%;
.content {
+ display: -webkit-flex;
display: flex;
+ -webkit-flex-direction: column;
flex-direction: column;
width: 100%;
}
@@ -42,8 +57,10 @@
}
.boards-list {
+ display: -webkit-flex;
display: flex;
- height: 100%;
+ -webkit-flex: 1;
+ flex: 1;
min-height: 455px;
padding-top: 25px;
padding-right: ($gl-padding / 2);
@@ -52,17 +69,19 @@
}
.board {
+ display: -webkit-flex;
+ display: flex;
min-width: 400px;
max-width: 400px;
- height: 100%;
padding-right: ($gl-padding / 2);
padding-left: ($gl-padding / 2);
}
.board-inner {
+ display: -webkit-flex;
display: flex;
+ -webkit-flex-direction: column;
flex-direction: column;
- height: 100%;
width: 100%;
font-size: $issue-boards-font-size;
background: $background-color;
@@ -162,6 +181,7 @@
}
.board-list {
+ -webkit-flex: 1;
flex: 1;
margin: 0;
padding: 5px;
diff --git a/app/views/projects/boards/index.html.haml b/app/views/projects/boards/index.html.haml
index 515638b5fd4..620cdb12a35 100644
--- a/app/views/projects/boards/index.html.haml
+++ b/app/views/projects/boards/index.html.haml
@@ -4,6 +4,7 @@
- content_for :page_specific_javascripts do
= page_specific_javascript_tag('boards/boards_bundle.js')
+ = page_specific_javascript_tag('boards/test_utils/simulate_drag.js') if Rails.env.test?
= render "projects/issues/head"
diff --git a/config/application.rb b/config/application.rb
index cd2d51d5908..0c136623477 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -86,6 +86,7 @@ module Gitlab
config.assets.precompile << "network/network_bundle.js"
config.assets.precompile << "profile/profile_bundle.js"
config.assets.precompile << "boards/boards_bundle.js"
+ config.assets.precompile << "boards/test_utils/simulate_drag.js"
config.assets.precompile << "lib/utils/*.js"
config.assets.precompile << "lib/*.js"
config.assets.precompile << "u2f.js"
diff --git a/spec/features/boards/boards_spec.rb b/spec/features/boards/boards_spec.rb
new file mode 100644
index 00000000000..6c514598653
--- /dev/null
+++ b/spec/features/boards/boards_spec.rb
@@ -0,0 +1,71 @@
+require 'rails_helper'
+
+describe 'Issue Boards', feature: true, js: true do
+ let(:project) { create(:project) }
+ let(:user) { create(:user) }
+
+ before do
+ project.team << [user, :master]
+ login_as(user)
+
+ visit namespace_project_boards_path(project.namespace, project)
+ end
+
+ it 'shows default lists' do
+ lists = all('.board')
+
+ page.within lists.first do
+ expect(page).to have_content 'Backlog'
+ end
+
+ page.within lists.last do
+ expect(page).to have_content 'Done'
+ end
+ end
+
+ it 'removes blank state list' do
+ click_button 'Nevermind, i\'ll use my own'
+
+ expect(page).to have_selector('.board', count: 2)
+ end
+
+ it 'can drag card to new list' do
+ sleep 0.5
+ lists = all('.board')
+ drag_to(list_from_index: 0, list_to_index: 1)
+
+ page.within lists[1].find('.board-list') do
+ expect(page).to have_content('Test')
+ expect(page).to have_selector('.card', count: 2)
+
+ page.within first('.card .card-footer') do
+ expect(page).to have_content 'Frontend'
+ end
+ end
+ end
+
+ it 'removes all labels from card' do
+ sleep 0.5
+ lists = all('.board')
+ drag_to(list_from_index: 1, list_to_index: 3)
+
+ page.within lists[3].find('.board-list') do
+ expect(page).to have_content('Frontend bug')
+ expect(page).to have_selector('.card', count: 2)
+
+ page.within first('.card .card-footer') do
+ expect(page).not_to have_content 'Frontend'
+ end
+ end
+
+ page.within lists[1].find('.board-list') do
+ expect(page).not_to have_content('Frontend bug')
+ expect(page).not_to have_selector('.card')
+ end
+ end
+
+ def drag_to(list_from_index: 0, card_index: 0, to_index: 0, list_to_index: 0)
+ evaluate_script("simulateDrag({scrollable: document.getElementById('board-app'), from: {el: $('.board-list').eq(#{list_from_index}).get(0), index: #{card_index}}, to: {el: $('.board-list').eq(#{list_to_index}).get(0), index: #{to_index}}});")
+ sleep 1
+ end
+end