summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke "Jared" Bennett <lbennett@gitlab.com>2017-04-05 16:58:01 +0100
committerLuke "Jared" Bennett <lbennett@gitlab.com>2017-04-05 18:34:13 +0100
commit5e3fa0255341fea8d0842453ff034c3bf5f00ba2 (patch)
tree44f08bdd9599641786b7fe2183715efa72af2cef
parent2b92f91038ad24a2ff3a6607f826cd8e518d8aa2 (diff)
downloadgitlab-ce-5e3fa0255341fea8d0842453ff034c3bf5f00ba2.tar.gz
Added resolvable discussion frontend
-rw-r--r--app/assets/javascripts/comment_type_toggle.js32
-rw-r--r--app/assets/javascripts/gl_form.js16
-rw-r--r--app/assets/javascripts/notes.js2
-rw-r--r--app/assets/stylesheets/pages/note_form.scss55
-rw-r--r--app/views/projects/notes/_form.html.haml21
-rw-r--r--app/views/shared/_comment_type_toggle.html.haml0
-rw-r--r--spec/javascripts/comment_type_toggle_spec.js79
7 files changed, 200 insertions, 5 deletions
diff --git a/app/assets/javascripts/comment_type_toggle.js b/app/assets/javascripts/comment_type_toggle.js
new file mode 100644
index 00000000000..75b6f60cabb
--- /dev/null
+++ b/app/assets/javascripts/comment_type_toggle.js
@@ -0,0 +1,32 @@
+import DropLab from '@gitlab-org/droplab';
+import InputSetter from '@gitlab-org/droplab/dist/plugins/InputSetter';
+
+class CommentTypeToggle {
+ constructor(trigger, list, input, button, secondaryButton) {
+ this.trigger = trigger;
+ this.list = list;
+ this.input = input;
+ this.button = button;
+ this.secondaryButton = secondaryButton;
+ }
+
+ initDroplab() {
+ this.droplab = new DropLab();
+ this.droplab.init(this.trigger, this.list, [InputSetter], {
+ InputSetter: [{
+ input: this.input,
+ valueAttribute: 'data-value',
+ },
+ {
+ input: this.button,
+ valueAttribute: 'data-button-text',
+ },
+ {
+ input: this.secondaryButton,
+ valueAttribute: 'data-secondary-button-text',
+ }],
+ });
+ }
+}
+
+export default CommentTypeToggle;
diff --git a/app/assets/javascripts/gl_form.js b/app/assets/javascripts/gl_form.js
index e7c98e16581..06072faa472 100644
--- a/app/assets/javascripts/gl_form.js
+++ b/app/assets/javascripts/gl_form.js
@@ -3,6 +3,8 @@
/* global DropzoneInput */
/* global autosize */
+import CommentTypeToggle from './comment_type_toggle';
+
window.gl = window.gl || {};
function GLForm(form) {
@@ -41,6 +43,20 @@ GLForm.prototype.setupForm = function() {
this.form.find('.js-note-discard').hide();
this.form.show();
if (this.isAutosizeable) this.setupAutosize();
+
+ this.initCommentTypeToggle();
+};
+
+GLForm.prototype.initCommentTypeToggle = function () {
+ this.commentTypeToggle = new CommentTypeToggle(
+ this.form[0].querySelector('.js-comment-type-dropdown .dropdown-toggle'),
+ this.form[0].querySelector('.js-comment-type-dropdown .dropdown-menu'),
+ document.getElementById('note_type'),
+ this.form[0].querySelector('.js-comment-type-dropdown .js-comment-submit-button'),
+ document.querySelector('.js-note-target-close'),
+ );
+
+ this.commentTypeToggle.initDroplab();
};
GLForm.prototype.setupAutosize = function () {
diff --git a/app/assets/javascripts/notes.js b/app/assets/javascripts/notes.js
index 63a5d25a1dc..33749d6ed9e 100644
--- a/app/assets/javascripts/notes.js
+++ b/app/assets/javascripts/notes.js
@@ -452,7 +452,7 @@ require('./task_list');
form.addClass("js-main-target-form");
form.find("#note_line_code").remove();
form.find("#note_position").remove();
- form.find("#note_type").remove();
+ form.find("#note_type").val('');
form.find("#in_reply_to_discussion_id").remove();
form.find('.js-comment-resolve-button').closest('comment-and-resolve-btn').remove();
return this.parentTimeline = form.parents('.timeline');
diff --git a/app/assets/stylesheets/pages/note_form.scss b/app/assets/stylesheets/pages/note_form.scss
index 927bf9805ce..8bc988b40cb 100644
--- a/app/assets/stylesheets/pages/note_form.scss
+++ b/app/assets/stylesheets/pages/note_form.scss
@@ -310,3 +310,58 @@
margin-bottom: 10px;
}
}
+
+.comment-type-dropdown {
+ .dropdown-toggle .fa {
+ color: $white-light;
+ padding-right: 2px;
+ margin-top: 2px;
+ pointer-events: none;
+ }
+
+ .dropdown-menu {
+ top: initial;
+ bottom: 40px;
+ width: 297px;
+ }
+
+ .description {
+ display: inline-block;
+ white-space: normal;
+ margin-left: 8px;
+ padding-right: 33px;
+ }
+
+ li {
+ white-space: nowrap;
+ border-radius: 0;
+ cursor: pointer;
+ padding-top: 6px;
+
+ &:hover,
+ &:focus {
+ background-color: $dropdown-hover-color;
+ color: $white-light;
+ }
+
+ &.droplab-item-selected i {
+ visibility: visible;
+ }
+
+ i {
+ visibility: hidden;
+ }
+ }
+
+ i {
+ display: inline-block;
+ vertical-align: top;
+ padding-top: 2px;
+ }
+
+ .divider {
+ margin: 0 8px;
+ padding: 0;
+ border-top: $gray-darkest;
+ }
+}
diff --git a/app/views/projects/notes/_form.html.haml b/app/views/projects/notes/_form.html.haml
index 80db16ea578..58960670085 100644
--- a/app/views/projects/notes/_form.html.haml
+++ b/app/views/projects/notes/_form.html.haml
@@ -28,10 +28,23 @@
.error-alert
.note-form-actions.clearfix
- = f.submit 'Comment', class: "btn btn-nr btn-create append-right-10 comment-btn js-comment-button"
-
- - if @note.can_be_discussion_note?
- = submit_tag 'Start discussion', name: 'new_discussion', class: "btn btn-nr append-right-10 btn-inverted js-note-new-discussion"
+ .btn-group.append-right-10.comment-type-dropdown.js-comment-type-dropdown
+ = f.submit 'Comment', class: "btn btn-nr btn-create comment-btn js-comment-button js-comment-submit-button"
+ - if @note.can_be_discussion_note?
+ = button_tag type: 'button', class: 'btn btn-nr dropdown-toggle comment-btn js-comment-button js-note-new-discussion', data: { 'dropdown-trigger' => '#resolvable-comment-menu' } do
+ = icon('caret-down')
+ %ul#resolvable-comment-menu.dropdown-menu{ data: { dropdown: true } }
+ %li#comment{ data: { value: '', 'button-text' => 'Comment', 'secondary-button-text' => 'Comment & close merge request' }, class: 'droplab-item-selected' }
+ = icon('check')
+ .description
+ %strong Comment
+ %p Add a general comment to this merge request.
+ %li.divider
+ %li#discussion{ data: { value: 'DiscussionNote', 'button-text' => 'Start discussion', 'secondary-button-text' => 'Start discussion & close merge request' } }
+ = icon('check')
+ .description
+ %strong Start discussion
+ %p Discuss a specific suggestion or question that needs to be resolved.
= yield(:note_actions)
diff --git a/app/views/shared/_comment_type_toggle.html.haml b/app/views/shared/_comment_type_toggle.html.haml
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/app/views/shared/_comment_type_toggle.html.haml
diff --git a/spec/javascripts/comment_type_toggle_spec.js b/spec/javascripts/comment_type_toggle_spec.js
new file mode 100644
index 00000000000..d68c221f0ea
--- /dev/null
+++ b/spec/javascripts/comment_type_toggle_spec.js
@@ -0,0 +1,79 @@
+import CommentTypeToggle from '~/comment_type_toggle';
+import DropLab from '@gitlab-org/droplab';
+import InputSetter from '@gitlab-org/droplab/dist/plugins/InputSetter';
+
+describe('CommentTypeToggle', function () {
+ describe('class constructor', function () {
+ beforeEach(function () {
+ this.trigger = {};
+ this.list = {};
+ this.input = {};
+ this.button = {};
+
+ this.commentTypeToggle = new CommentTypeToggle(
+ this.trigger,
+ this.list,
+ this.input,
+ this.button,
+ );
+ });
+
+ it('should set .trigger', function () {
+ expect(this.commentTypeToggle.trigger).toBe(this.trigger);
+ });
+
+ it('should set .list', function () {
+ expect(this.commentTypeToggle.list).toBe(this.list);
+ });
+
+ it('should set .input', function () {
+ expect(this.commentTypeToggle.input).toBe(this.input);
+ });
+
+ it('should set .button', function () {
+ expect(this.commentTypeToggle.button).toBe(this.button);
+ });
+ });
+
+ describe('initDroplab', function () {
+ beforeEach(function () {
+ this.commentTypeToggle = {
+ trigger: {},
+ list: {},
+ input: {},
+ button: {},
+ };
+
+ this.droplab = jasmine.createSpyObj('droplab', ['addHook']);
+
+ spyOn(window, 'DropLab').and.returnValue(this.droplab);
+
+ this.initDroplab = CommentTypeToggle.prototype.initDroplab.call(this.commentTypeToggle);
+ });
+
+ it('should instantiate a DropLab instance', function () {
+ expect(window.DropLab).toHaveBeenCalled();
+ });
+
+ it('should set .droplab', function () {
+ expect(this.commentTypeToggle.droplab).toBe(this.droplab);
+ });
+
+ it('should call DropLab.prototype.addHook', function () {
+ expect(this.droplab.addHook).toHaveBeenCalledWith(
+ this.commentTypeToggle.trigger,
+ this.commentTypeToggle.list,
+ [InputSetter],
+ {
+ InputSetter: [{
+ input: this.commentTypeToggle.input,
+ valueAttribute: 'data-value',
+ }, {
+ input: this.commentTypeToggle.button,
+ valueAttribute: 'data-button-text',
+ }],
+ },
+ );
+ });
+ });
+});