diff options
author | Fatih Acet <acetfatih@gmail.com> | 2019-06-06 15:51:04 +0000 |
---|---|---|
committer | Fatih Acet <acetfatih@gmail.com> | 2019-06-06 15:51:04 +0000 |
commit | 9cbfcf9b2a9e70821568d802a9c8b3fb0c5a73ee (patch) | |
tree | 146e5393fff91d5b850494d0eb0fd1664c9fb6fa | |
parent | a90e9de349004b9c2202c16c66880861952d6758 (diff) | |
parent | 5bfc10060783e9e670a5a756e0bb55f7c655848f (diff) | |
download | gitlab-ce-9cbfcf9b2a9e70821568d802a9c8b3fb0c5a73ee.tar.gz |
Merge branch '62124-new-threaded-discussion-design' into 'master'
Resolve "New threaded discussion design"
Closes #62124
See merge request gitlab-org/gitlab-ce!28580
23 files changed, 208 insertions, 51 deletions
diff --git a/app/assets/javascripts/diffs/components/diff_content.vue b/app/assets/javascripts/diffs/components/diff_content.vue index 2b3d6d1a3fa..d59b1136677 100644 --- a/app/assets/javascripts/diffs/components/diff_content.vue +++ b/app/assets/javascripts/diffs/components/diff_content.vue @@ -8,6 +8,7 @@ import NotDiffableViewer from '~/vue_shared/components/diff_viewer/viewers/not_d import NoPreviewViewer from '~/vue_shared/components/diff_viewer/viewers/no_preview.vue'; import InlineDiffView from './inline_diff_view.vue'; import ParallelDiffView from './parallel_diff_view.vue'; +import userAvatarLink from '../../vue_shared/components/user_avatar/user_avatar_link.vue'; import NoteForm from '../../notes/components/note_form.vue'; import ImageDiffOverlay from './image_diff_overlay.vue'; import DiffDiscussions from './diff_discussions.vue'; @@ -26,6 +27,7 @@ export default { ImageDiffOverlay, NotDiffableViewer, NoPreviewViewer, + userAvatarLink, DiffFileDrafts: () => import('ee_component/batch_comments/components/diff_file_drafts.vue'), }, mixins: [diffLineNoteFormMixin, draftCommentsMixin], @@ -47,7 +49,7 @@ export default { }), ...mapGetters('diffs', ['isInlineView', 'isParallelView']), ...mapGetters('diffs', ['getCommentFormForDiffFile']), - ...mapGetters(['getNoteableData', 'noteableType']), + ...mapGetters(['getNoteableData', 'noteableType', 'getUserData']), diffMode() { return getDiffMode(this.diffFile); }, @@ -72,6 +74,9 @@ export default { diffFileHash() { return this.diffFile.file_hash; }, + author() { + return this.getUserData; + }, }, methods: { ...mapActions('diffs', ['saveDiffDiscussion', 'closeDiffFileCommentForm']), @@ -134,6 +139,14 @@ export default { :can-comment="getNoteableData.current_user.can_create_note" /> <div v-if="showNotesContainer" class="note-container"> + <user-avatar-link + v-if="diffFileCommentForm && author" + :link-href="author.path" + :img-src="author.avatar_url" + :img-alt="author.name" + :img-size="40" + class="d-none d-sm-block new-comment" + /> <diff-discussions v-if="diffFile.discussions.length" class="diff-file-discussions" diff --git a/app/assets/javascripts/diffs/components/diff_line_note_form.vue b/app/assets/javascripts/diffs/components/diff_line_note_form.vue index 41670b45798..c209b857652 100644 --- a/app/assets/javascripts/diffs/components/diff_line_note_form.vue +++ b/app/assets/javascripts/diffs/components/diff_line_note_form.vue @@ -4,11 +4,13 @@ import { s__ } from '~/locale'; import diffLineNoteFormMixin from 'ee_else_ce/notes/mixins/diff_line_note_form'; import noteForm from '../../notes/components/note_form.vue'; import autosave from '../../notes/mixins/autosave'; +import userAvatarLink from '../../vue_shared/components/user_avatar/user_avatar_link.vue'; import { DIFF_NOTE_TYPE } from '../constants'; export default { components: { noteForm, + userAvatarLink, }, mixins: [autosave, diffLineNoteFormMixin], props: { @@ -41,7 +43,16 @@ export default { diffViewType: state => state.diffs.diffViewType, }), ...mapGetters('diffs', ['getDiffFileByHash']), - ...mapGetters(['isLoggedIn', 'noteableType', 'getNoteableData', 'getNotesDataByProp']), + ...mapGetters([ + 'isLoggedIn', + 'noteableType', + 'getNoteableData', + 'getNotesDataByProp', + 'getUserData', + ]), + author() { + return this.getUserData; + }, formData() { return { noteableData: this.noteableData, @@ -99,6 +110,14 @@ export default { <template> <div class="content discussion-form discussion-form-container discussion-notes"> + <user-avatar-link + v-if="author" + :link-href="author.path" + :img-src="author.avatar_url" + :img-alt="author.name" + :img-size="40" + class="d-none d-sm-block" + /> <note-form ref="noteForm" :is-editing="true" diff --git a/app/assets/javascripts/notes.js b/app/assets/javascripts/notes.js index 1c9ca180100..a7156bd2406 100644 --- a/app/assets/javascripts/notes.js +++ b/app/assets/javascripts/notes.js @@ -990,6 +990,14 @@ export default class Notes { form.find('#note_position').val(dataHolder.attr('data-position')); form + .prepend( + `<div class="avatar-note-form-holder"><div class="content"><a href="${escape( + gon.current_username, + )}" class="user-avatar-link d-none d-sm-block"><img class="avatar s40" src="${encodeURI( + gon.current_user_avatar_url, + )}" alt="${escape(gon.current_user_fullname)}" /></a></div></div>`, + ) + .append('</div>') .find('.js-close-discussion-note-form') .show() .removeClass('hide'); @@ -1025,6 +1033,9 @@ export default class Notes { target: $link, lineType: link.dataset.lineType, showReplyInput, + currentUsername: gon.current_username, + currentUserAvatar: gon.current_user_avatar_url, + currentUserFullname: gon.current_user_fullname, }); } @@ -1053,7 +1064,15 @@ export default class Notes { this.setupDiscussionNoteForm($link, newForm); } - toggleDiffNote({ target, lineType, forceShow, showReplyInput = false }) { + toggleDiffNote({ + target, + lineType, + forceShow, + showReplyInput = false, + currentUsername, + currentUserAvatar, + currentUserFullname, + }) { var $link, addForm, hasNotes, @@ -1546,7 +1565,9 @@ export default class Notes { <div class="note-header"> <div class="note-header-info"> <a href="/${_.escape(currentUsername)}"> - <span class="d-none d-sm-inline-block">${_.escape(currentUsername)}</span> + <span class="d-none d-sm-inline-block bold">${_.escape( + currentUsername, + )}</span> <span class="note-headline-light">${_.escape(currentUsername)}</span> </a> </div> diff --git a/app/assets/javascripts/notes/components/note_header.vue b/app/assets/javascripts/notes/components/note_header.vue index 5c59c0c32dd..fbf82fab9e9 100644 --- a/app/assets/javascripts/notes/components/note_header.vue +++ b/app/assets/javascripts/notes/components/note_header.vue @@ -82,7 +82,7 @@ export default { :data-username="author.username" > <slot name="note-header-info"></slot> - <span class="note-header-author-name">{{ author.name }}</span> + <span class="note-header-author-name bold">{{ author.name }}</span> <span v-if="author.status_tooltip_html" v-html="author.status_tooltip_html"></span> <span class="note-headline-light">@{{ author.username }}</span> </a> diff --git a/app/assets/javascripts/notes/components/noteable_discussion.vue b/app/assets/javascripts/notes/components/noteable_discussion.vue index 2c549e7abdd..eb6a4a67fff 100644 --- a/app/assets/javascripts/notes/components/noteable_discussion.vue +++ b/app/assets/javascripts/notes/components/noteable_discussion.vue @@ -87,7 +87,11 @@ export default { 'unresolvedDiscussionsCount', 'hasUnresolvedDiscussions', 'showJumpToNextDiscussion', + 'getUserData', ]), + currentUser() { + return this.getUserData; + }, author() { return this.firstNote.author; }, @@ -377,6 +381,14 @@ Please check your network connection and try again.`; :class="{ 'is-replying': isReplying }" class="discussion-reply-holder" > + <user-avatar-link + v-if="!isReplying && currentUser" + :link-href="currentUser.path" + :img-src="currentUser.avatar_url" + :img-alt="currentUser.name" + :img-size="40" + class="d-none d-sm-block" + /> <discussion-actions v-if="!isReplying && userCanReply" :discussion="discussion" @@ -388,18 +400,27 @@ Please check your network connection and try again.`; @resolve="resolveHandler" @jumpToNextDiscussion="jumpToNextDiscussion" /> - <note-form - v-if="isReplying" - ref="noteForm" - :discussion="discussion" - :is-editing="false" - :line="diffLine" - save-button-title="Comment" - :autosave-key="autosaveKey" - @handleFormUpdateAddToReview="addReplyToReview" - @handleFormUpdate="saveReply" - @cancelForm="cancelReplyForm" - /> + <div v-if="isReplying" class="avatar-note-form-holder"> + <user-avatar-link + v-if="currentUser" + :link-href="currentUser.path" + :img-src="currentUser.avatar_url" + :img-alt="currentUser.name" + :img-size="40" + class="d-none d-sm-block" + /> + <note-form + ref="noteForm" + :discussion="discussion" + :is-editing="false" + :line="diffLine" + save-button-title="Comment" + :autosave-key="autosaveKey" + @handleFormUpdateAddToReview="addReplyToReview" + @handleFormUpdate="saveReply" + @cancelForm="cancelReplyForm" + /> + </div> <note-signed-out-widget v-if="!userCanReply" /> </div> </template> diff --git a/app/assets/javascripts/vue_shared/components/notes/placeholder_note.vue b/app/assets/javascripts/vue_shared/components/notes/placeholder_note.vue index a50f49c1279..baed26a157c 100644 --- a/app/assets/javascripts/vue_shared/components/notes/placeholder_note.vue +++ b/app/assets/javascripts/vue_shared/components/notes/placeholder_note.vue @@ -51,7 +51,7 @@ export default { <div class="note-header"> <div class="note-header-info"> <a :href="getUserData.path"> - <span class="d-none d-sm-inline-block">{{ getUserData.name }}</span> + <span class="d-none d-sm-inline-block bold">{{ getUserData.name }}</span> <span class="note-headline-light">@{{ getUserData.username }}</span> </a> </div> diff --git a/app/assets/stylesheets/framework/buttons.scss b/app/assets/stylesheets/framework/buttons.scss index 97a763671ba..767832e242c 100644 --- a/app/assets/stylesheets/framework/buttons.scss +++ b/app/assets/stylesheets/framework/buttons.scss @@ -249,7 +249,7 @@ padding: 6px 16px; border-color: $border-color; color: $gray-darkest; - background-color: $gray-light; + background-color: $white-light; &:hover, &:active, @@ -258,7 +258,6 @@ box-shadow: none; border-color: lighten($blue-300, 20%); color: $gray-darkest; - background-color: $gray-light; } } diff --git a/app/assets/stylesheets/framework/files.scss b/app/assets/stylesheets/framework/files.scss index ef6f0633150..536a26a6ffe 100644 --- a/app/assets/stylesheets/framework/files.scss +++ b/app/assets/stylesheets/framework/files.scss @@ -453,6 +453,28 @@ span.idiff { } } + .note-container { + .user-avatar-link.new-comment { + position: absolute; + margin: 40px $gl-padding 0 116px; + + ~ .note-edit-form form.edit-note { + @include media-breakpoint-up(sm) { + margin-left: $note-icon-gutter-width; + } + } + } + } + + .diff-discussions:not(:last-child) .discussion .discussion-body { + padding-bottom: $gl-padding; + + .discussion-reply-holder { + border-bottom: 1px solid $gray-100; + border-radius: 0; + } + } + .md-previewer { padding: $gl-padding; } diff --git a/app/assets/stylesheets/framework/timeline.scss b/app/assets/stylesheets/framework/timeline.scss index e8176e59c19..42a739e88f7 100644 --- a/app/assets/stylesheets/framework/timeline.scss +++ b/app/assets/stylesheets/framework/timeline.scss @@ -42,8 +42,8 @@ } } - .avatar { - margin-right: 15px; + img.avatar { + margin-right: $gl-padding; } .controls { diff --git a/app/assets/stylesheets/pages/diff.scss b/app/assets/stylesheets/pages/diff.scss index 5e5d298f8f2..3b0d740def3 100644 --- a/app/assets/stylesheets/pages/diff.scss +++ b/app/assets/stylesheets/pages/diff.scss @@ -1008,6 +1008,10 @@ table.code { display: block; } } + + .note-edit-form { + margin-left: $note-icon-gutter-width; + } } .discussion-body .image .frame { diff --git a/app/assets/stylesheets/pages/issues.scss b/app/assets/stylesheets/pages/issues.scss index c7d2369a6b8..48289c8f381 100644 --- a/app/assets/stylesheets/pages/issues.scss +++ b/app/assets/stylesheets/pages/issues.scss @@ -258,8 +258,15 @@ ul.related-merge-requests > li { } } -.discussion-reply-holder .note-edit-form { - display: block; +.discussion-reply-holder { + .avatar-note-form-holder .note-edit-form { + display: block; + margin-left: $note-icon-gutter-width; + + @include media-breakpoint-down(xs) { + margin-left: 0; + } + } } .issue-sort-dropdown { diff --git a/app/assets/stylesheets/pages/note_form.scss b/app/assets/stylesheets/pages/note_form.scss index 267fdfa5d86..c6bac33e888 100644 --- a/app/assets/stylesheets/pages/note_form.scss +++ b/app/assets/stylesheets/pages/note_form.scss @@ -59,6 +59,7 @@ border-radius: $border-radius-base; transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; + background-color: $white-light; &.is-focused { @extend .form-control:focus; @@ -173,6 +174,16 @@ .discussion-form { background-color: $white-light; + + @include media-breakpoint-down(xs) { + .user-avatar-link { + display: none; + } + + .note-edit-form { + margin-left: 0; + } + } } table { @@ -239,13 +250,25 @@ table { .diff-file, .commit-diff { .discussion-reply-holder { - background-color: $white-light; + background-color: $gray-light; border-radius: 0 0 3px 3px; padding: $gl-padding; + border-top: 1px solid $gray-100; + + + .new-note { + background-color: $gray-light; + border-top: 1px solid $gray-100; + } &.is-replying { padding-bottom: $gl-padding; } + + .user-avatar-link { + img { + margin-top: -3px; + } + } } } diff --git a/app/assets/stylesheets/pages/notes.scss b/app/assets/stylesheets/pages/notes.scss index 26626217043..da341121087 100644 --- a/app/assets/stylesheets/pages/notes.scss +++ b/app/assets/stylesheets/pages/notes.scss @@ -80,21 +80,17 @@ $note-form-margin-left: 72px; } } - li.note { - border-bottom: 1px solid $border-color; - } - .replies-toggle { background-color: $gray-light; padding: $gl-padding-8 $gl-padding; + border-top: 1px solid $gray-100; + border-bottom: 1px solid $gray-100; .collapse-replies-btn:hover { color: $blue-600; } &.expanded { - border-bottom: 1px solid $border-color; - span { cursor: pointer; } @@ -211,8 +207,13 @@ $note-form-margin-left: 72px; display: none; } + .user-avatar-link img { + margin-top: $gl-padding-8; + } + .note-edit-form { display: block; + margin-left: 0; &.current-note-edit-form + .note-awards { display: none; @@ -519,12 +520,30 @@ $note-form-margin-left: 72px; } } -.commit-diff { - .notes-content { - background-color: $white-light; +.code-commit .notes-content, +.diff-viewer > .image ~ .note-container { + background-color: $white-light; + + .avatar-note-form-holder { + .user-avatar-link img { + margin: 13px $gl-padding $gl-padding; + } + + form, + ~ .discussion-form-container { + padding: $gl-padding; + + @include media-breakpoint-up(sm) { + margin-left: $note-icon-gutter-width; + } + } } } +.diff-viewer > .image ~ .note-container form.new-note { + margin-left: 0; +} + .discussion-header, .note-header-info { a { diff --git a/app/views/discussions/_notes.html.haml b/app/views/discussions/_notes.html.haml index 30b00ca86b3..0a5541c3e82 100644 --- a/app/views/discussions/_notes.html.haml +++ b/app/views/discussions/_notes.html.haml @@ -19,20 +19,24 @@ .discussion-reply-holder - if can_create_note? + %a.user-avatar-link.d-none.d-sm-block{ href: user_path(current_user) } + = image_tag avatar_icon_for_user(current_user), alt: current_user.to_reference, class: 'avatar s40' - if discussion.potentially_resolvable? - line_type = local_assigns.fetch(:line_type, nil) - .btn-group.discussion-with-resolve-btn{ role: "group" } - .btn-group{ role: "group" } - = link_to_reply_discussion(discussion, line_type) + .discussion-with-resolve-btn + .btn-group.discussion-with-resolve-btn{ role: "group" } + .btn-group{ role: "group" } + = link_to_reply_discussion(discussion, line_type) - = render "discussions/resolve_all", discussion: discussion + = render "discussions/resolve_all", discussion: discussion - .btn-group.discussion-actions - = render "discussions/new_issue_for_discussion", discussion: discussion, merge_request: discussion.noteable - = render "discussions/jump_to_next", discussion: discussion + .btn-group.discussion-actions + = render "discussions/new_issue_for_discussion", discussion: discussion, merge_request: discussion.noteable + = render "discussions/jump_to_next", discussion: discussion - else - = link_to_reply_discussion(discussion) + .discussion-with-resolve-btn + = link_to_reply_discussion(discussion) - elsif !current_user .disabled-comment.text-center Please diff --git a/app/views/projects/diffs/_parallel_view.html.haml b/app/views/projects/diffs/_parallel_view.html.haml index 311b0be19ab..9587ea4696b 100644 --- a/app/views/projects/diffs/_parallel_view.html.haml +++ b/app/views/projects/diffs/_parallel_view.html.haml @@ -1,7 +1,7 @@ / Side-by-side diff view .text-file{ data: diff_view_data } - %table.diff-wrap-lines.code.js-syntax-highlight + %table.diff-wrap-lines.code.code-commit.js-syntax-highlight - diff_file.parallel_diff_lines.each do |line| - left = line[:left] - right = line[:right] diff --git a/app/views/projects/diffs/_text_file.html.haml b/app/views/projects/diffs/_text_file.html.haml index 018c5b38536..641a0689c26 100644 --- a/app/views/projects/diffs/_text_file.html.haml +++ b/app/views/projects/diffs/_text_file.html.haml @@ -3,7 +3,7 @@ .suppressed-container %a.show-suppressed-diff.cursor-pointer.js-show-suppressed-diff= _("Changes suppressed. Click to show.") -%table.text-file.diff-wrap-lines.code.js-syntax-highlight.commit-diff{ data: diff_view_data, class: too_big ? 'hide' : '' } +%table.text-file.diff-wrap-lines.code.code-commit.js-syntax-highlight.commit-diff{ data: diff_view_data, class: too_big ? 'hide' : '' } = render partial: "projects/diffs/line", collection: diff_file.highlighted_diff_lines, as: :line, diff --git a/app/views/projects/merge_requests/conflicts/components/_inline_conflict_lines.html.haml b/app/views/projects/merge_requests/conflicts/components/_inline_conflict_lines.html.haml index 03226de120d..7bd5c437942 100644 --- a/app/views/projects/merge_requests/conflicts/components/_inline_conflict_lines.html.haml +++ b/app/views/projects/merge_requests/conflicts/components/_inline_conflict_lines.html.haml @@ -1,5 +1,5 @@ %inline-conflict-lines{ "inline-template" => "true", ":file" => "file" } - %table.diff-wrap-lines.code.js-syntax-highlight + %table.diff-wrap-lines.code.code-commit.js-syntax-highlight %tr.line_holder.diff-inline{ "v-for" => "line in file.inlineLines" } %td.diff-line-num.new_line{ ":class" => "lineCssClass(line)", "v-if" => "!line.isHeader" } %a {{line.new_line}} diff --git a/app/views/shared/notes/_note.html.haml b/app/views/shared/notes/_note.html.haml index 6fec435cc87..5c9dd72418e 100644 --- a/app/views/shared/notes/_note.html.haml +++ b/app/views/shared/notes/_note.html.haml @@ -31,7 +31,7 @@ .note-header .note-header-info %a{ href: user_path(note.author) } - %span.note-header-author-name + %span.note-header-author-name.bold = sanitize(note.author.name) = user_status(note.author) %span.note-headline-light diff --git a/changelogs/unreleased/61323-snippet-copy-icon-button-is-misaligned.yml b/changelogs/unreleased/61323-snippet-copy-icon-button-is-misaligned.yml index 6f8c82c2dc8..94666ac12ec 100644 --- a/changelogs/unreleased/61323-snippet-copy-icon-button-is-misaligned.yml +++ b/changelogs/unreleased/61323-snippet-copy-icon-button-is-misaligned.yml @@ -1,5 +1,5 @@ --- title: Resolve Snippet icon button is misaligned merge_request: 28522 -author: Marcel van Remmerden +author: type: other diff --git a/changelogs/unreleased/61324-non-project-snippet-new-snippet-button-should-be-green-outline.yml b/changelogs/unreleased/61324-non-project-snippet-new-snippet-button-should-be-green-outline.yml index 350fd525a30..a7f5706058d 100644 --- a/changelogs/unreleased/61324-non-project-snippet-new-snippet-button-should-be-green-outline.yml +++ b/changelogs/unreleased/61324-non-project-snippet-new-snippet-button-should-be-green-outline.yml @@ -1,5 +1,5 @@ --- title: Give New Snippet button green outline merge_request: 28559 -author: Marcel van Remmerden +author: type: other diff --git a/changelogs/unreleased/61339-Add-underline-to-attach-a-file.yml b/changelogs/unreleased/61339-Add-underline-to-attach-a-file.yml index c3808709fca..e446459ffc8 100644 --- a/changelogs/unreleased/61339-Add-underline-to-attach-a-file.yml +++ b/changelogs/unreleased/61339-Add-underline-to-attach-a-file.yml @@ -1,5 +1,5 @@ --- title: Add hover and focus to Attach a file merge_request: 28682 -author: Marcel van Remmerden +author: type: fixed diff --git a/changelogs/unreleased/61988-collapse-icon-on-merge-request-diff-larger-than-profile-picture.yml b/changelogs/unreleased/61988-collapse-icon-on-merge-request-diff-larger-than-profile-picture.yml index 46d3f439a44..4d2f73ce2ff 100644 --- a/changelogs/unreleased/61988-collapse-icon-on-merge-request-diff-larger-than-profile-picture.yml +++ b/changelogs/unreleased/61988-collapse-icon-on-merge-request-diff-larger-than-profile-picture.yml @@ -1,5 +1,5 @@ --- -title: Change collapse icon size to size of profile picture +title: Change collapse icon size to size of profile picture merge_request: 28512 -author: Marcel van Remmerden +author: type: other diff --git a/changelogs/unreleased/62124-new-threaded-discussion-design.yml b/changelogs/unreleased/62124-new-threaded-discussion-design.yml new file mode 100644 index 00000000000..6614e05be74 --- /dev/null +++ b/changelogs/unreleased/62124-new-threaded-discussion-design.yml @@ -0,0 +1,5 @@ +--- +title: Implement borderless discussion design with new reply field +merge_request: 28580 +author: +type: added |