diff options
author | Luke "Jared" Bennett <lbennett@gitlab.com> | 2017-04-05 16:58:01 +0100 |
---|---|---|
committer | Luke "Jared" Bennett <lbennett@gitlab.com> | 2017-04-05 18:34:13 +0100 |
commit | 5e3fa0255341fea8d0842453ff034c3bf5f00ba2 (patch) | |
tree | 44f08bdd9599641786b7fe2183715efa72af2cef | |
parent | 2b92f91038ad24a2ff3a6607f826cd8e518d8aa2 (diff) | |
download | gitlab-ce-5e3fa0255341fea8d0842453ff034c3bf5f00ba2.tar.gz |
Added resolvable discussion frontend
-rw-r--r-- | app/assets/javascripts/comment_type_toggle.js | 32 | ||||
-rw-r--r-- | app/assets/javascripts/gl_form.js | 16 | ||||
-rw-r--r-- | app/assets/javascripts/notes.js | 2 | ||||
-rw-r--r-- | app/assets/stylesheets/pages/note_form.scss | 55 | ||||
-rw-r--r-- | app/views/projects/notes/_form.html.haml | 21 | ||||
-rw-r--r-- | app/views/shared/_comment_type_toggle.html.haml | 0 | ||||
-rw-r--r-- | spec/javascripts/comment_type_toggle_spec.js | 79 |
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', + }], + }, + ); + }); + }); +}); |