Commit 9cbfcf9b authored by Fatih Acet's avatar Fatih Acet

Merge branch '62124-new-threaded-discussion-design' into 'master'

Resolve "New threaded discussion design"

Closes #62124

See merge request gitlab-org/gitlab-ce!28580
parents a90e9de3 5bfc1006
...@@ -8,6 +8,7 @@ import NotDiffableViewer from '~/vue_shared/components/diff_viewer/viewers/not_d ...@@ -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 NoPreviewViewer from '~/vue_shared/components/diff_viewer/viewers/no_preview.vue';
import InlineDiffView from './inline_diff_view.vue'; import InlineDiffView from './inline_diff_view.vue';
import ParallelDiffView from './parallel_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 NoteForm from '../../notes/components/note_form.vue';
import ImageDiffOverlay from './image_diff_overlay.vue'; import ImageDiffOverlay from './image_diff_overlay.vue';
import DiffDiscussions from './diff_discussions.vue'; import DiffDiscussions from './diff_discussions.vue';
...@@ -26,6 +27,7 @@ export default { ...@@ -26,6 +27,7 @@ export default {
ImageDiffOverlay, ImageDiffOverlay,
NotDiffableViewer, NotDiffableViewer,
NoPreviewViewer, NoPreviewViewer,
userAvatarLink,
DiffFileDrafts: () => import('ee_component/batch_comments/components/diff_file_drafts.vue'), DiffFileDrafts: () => import('ee_component/batch_comments/components/diff_file_drafts.vue'),
}, },
mixins: [diffLineNoteFormMixin, draftCommentsMixin], mixins: [diffLineNoteFormMixin, draftCommentsMixin],
...@@ -47,7 +49,7 @@ export default { ...@@ -47,7 +49,7 @@ export default {
}), }),
...mapGetters('diffs', ['isInlineView', 'isParallelView']), ...mapGetters('diffs', ['isInlineView', 'isParallelView']),
...mapGetters('diffs', ['getCommentFormForDiffFile']), ...mapGetters('diffs', ['getCommentFormForDiffFile']),
...mapGetters(['getNoteableData', 'noteableType']), ...mapGetters(['getNoteableData', 'noteableType', 'getUserData']),
diffMode() { diffMode() {
return getDiffMode(this.diffFile); return getDiffMode(this.diffFile);
}, },
...@@ -72,6 +74,9 @@ export default { ...@@ -72,6 +74,9 @@ export default {
diffFileHash() { diffFileHash() {
return this.diffFile.file_hash; return this.diffFile.file_hash;
}, },
author() {
return this.getUserData;
},
}, },
methods: { methods: {
...mapActions('diffs', ['saveDiffDiscussion', 'closeDiffFileCommentForm']), ...mapActions('diffs', ['saveDiffDiscussion', 'closeDiffFileCommentForm']),
...@@ -134,6 +139,14 @@ export default { ...@@ -134,6 +139,14 @@ export default {
:can-comment="getNoteableData.current_user.can_create_note" :can-comment="getNoteableData.current_user.can_create_note"
/> />
<div v-if="showNotesContainer" class="note-container"> <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 <diff-discussions
v-if="diffFile.discussions.length" v-if="diffFile.discussions.length"
class="diff-file-discussions" class="diff-file-discussions"
......
...@@ -4,11 +4,13 @@ import { s__ } from '~/locale'; ...@@ -4,11 +4,13 @@ import { s__ } from '~/locale';
import diffLineNoteFormMixin from 'ee_else_ce/notes/mixins/diff_line_note_form'; import diffLineNoteFormMixin from 'ee_else_ce/notes/mixins/diff_line_note_form';
import noteForm from '../../notes/components/note_form.vue'; import noteForm from '../../notes/components/note_form.vue';
import autosave from '../../notes/mixins/autosave'; import autosave from '../../notes/mixins/autosave';
import userAvatarLink from '../../vue_shared/components/user_avatar/user_avatar_link.vue';
import { DIFF_NOTE_TYPE } from '../constants'; import { DIFF_NOTE_TYPE } from '../constants';
export default { export default {
components: { components: {
noteForm, noteForm,
userAvatarLink,
}, },
mixins: [autosave, diffLineNoteFormMixin], mixins: [autosave, diffLineNoteFormMixin],
props: { props: {
...@@ -41,7 +43,16 @@ export default { ...@@ -41,7 +43,16 @@ export default {
diffViewType: state => state.diffs.diffViewType, diffViewType: state => state.diffs.diffViewType,
}), }),
...mapGetters('diffs', ['getDiffFileByHash']), ...mapGetters('diffs', ['getDiffFileByHash']),
...mapGetters(['isLoggedIn', 'noteableType', 'getNoteableData', 'getNotesDataByProp']), ...mapGetters([
'isLoggedIn',
'noteableType',
'getNoteableData',
'getNotesDataByProp',
'getUserData',
]),
author() {
return this.getUserData;
},
formData() { formData() {
return { return {
noteableData: this.noteableData, noteableData: this.noteableData,
...@@ -99,6 +110,14 @@ export default { ...@@ -99,6 +110,14 @@ export default {
<template> <template>
<div class="content discussion-form discussion-form-container discussion-notes"> <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 <note-form
ref="noteForm" ref="noteForm"
:is-editing="true" :is-editing="true"
......
...@@ -990,6 +990,14 @@ export default class Notes { ...@@ -990,6 +990,14 @@ export default class Notes {
form.find('#note_position').val(dataHolder.attr('data-position')); form.find('#note_position').val(dataHolder.attr('data-position'));
form 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') .find('.js-close-discussion-note-form')
.show() .show()
.removeClass('hide'); .removeClass('hide');
...@@ -1025,6 +1033,9 @@ export default class Notes { ...@@ -1025,6 +1033,9 @@ export default class Notes {
target: $link, target: $link,
lineType: link.dataset.lineType, lineType: link.dataset.lineType,
showReplyInput, showReplyInput,
currentUsername: gon.current_username,
currentUserAvatar: gon.current_user_avatar_url,
currentUserFullname: gon.current_user_fullname,
}); });
} }
...@@ -1053,7 +1064,15 @@ export default class Notes { ...@@ -1053,7 +1064,15 @@ export default class Notes {
this.setupDiscussionNoteForm($link, newForm); this.setupDiscussionNoteForm($link, newForm);
} }
toggleDiffNote({ target, lineType, forceShow, showReplyInput = false }) { toggleDiffNote({
target,
lineType,
forceShow,
showReplyInput = false,
currentUsername,
currentUserAvatar,
currentUserFullname,
}) {
var $link, var $link,
addForm, addForm,
hasNotes, hasNotes,
...@@ -1546,7 +1565,9 @@ export default class Notes { ...@@ -1546,7 +1565,9 @@ export default class Notes {
<div class="note-header"> <div class="note-header">
<div class="note-header-info"> <div class="note-header-info">
<a href="/${_.escape(currentUsername)}"> <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> <span class="note-headline-light">${_.escape(currentUsername)}</span>
</a> </a>
</div> </div>
......
...@@ -82,7 +82,7 @@ export default { ...@@ -82,7 +82,7 @@ export default {
:data-username="author.username" :data-username="author.username"
> >
<slot name="note-header-info"></slot> <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 v-if="author.status_tooltip_html" v-html="author.status_tooltip_html"></span>
<span class="note-headline-light">@{{ author.username }}</span> <span class="note-headline-light">@{{ author.username }}</span>
</a> </a>
......
...@@ -87,7 +87,11 @@ export default { ...@@ -87,7 +87,11 @@ export default {
'unresolvedDiscussionsCount', 'unresolvedDiscussionsCount',
'hasUnresolvedDiscussions', 'hasUnresolvedDiscussions',
'showJumpToNextDiscussion', 'showJumpToNextDiscussion',
'getUserData',
]), ]),
currentUser() {
return this.getUserData;
},
author() { author() {
return this.firstNote.author; return this.firstNote.author;
}, },
...@@ -377,6 +381,14 @@ Please check your network connection and try again.`; ...@@ -377,6 +381,14 @@ Please check your network connection and try again.`;
:class="{ 'is-replying': isReplying }" :class="{ 'is-replying': isReplying }"
class="discussion-reply-holder" 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 <discussion-actions
v-if="!isReplying && userCanReply" v-if="!isReplying && userCanReply"
:discussion="discussion" :discussion="discussion"
...@@ -388,18 +400,27 @@ Please check your network connection and try again.`; ...@@ -388,18 +400,27 @@ Please check your network connection and try again.`;
@resolve="resolveHandler" @resolve="resolveHandler"
@jumpToNextDiscussion="jumpToNextDiscussion" @jumpToNextDiscussion="jumpToNextDiscussion"
/> />
<note-form <div v-if="isReplying" class="avatar-note-form-holder">
v-if="isReplying" <user-avatar-link
ref="noteForm" v-if="currentUser"
:discussion="discussion" :link-href="currentUser.path"
:is-editing="false" :img-src="currentUser.avatar_url"
:line="diffLine" :img-alt="currentUser.name"
save-button-title="Comment" :img-size="40"
:autosave-key="autosaveKey" class="d-none d-sm-block"
@handleFormUpdateAddToReview="addReplyToReview" />
@handleFormUpdate="saveReply" <note-form
@cancelForm="cancelReplyForm" 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" /> <note-signed-out-widget v-if="!userCanReply" />
</div> </div>
</template> </template>
......
...@@ -51,7 +51,7 @@ export default { ...@@ -51,7 +51,7 @@ export default {
<div class="note-header"> <div class="note-header">
<div class="note-header-info"> <div class="note-header-info">
<a :href="getUserData.path"> <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> <span class="note-headline-light">@{{ getUserData.username }}</span>
</a> </a>
</div> </div>
......
...@@ -249,7 +249,7 @@ ...@@ -249,7 +249,7 @@
padding: 6px 16px; padding: 6px 16px;
border-color: $border-color; border-color: $border-color;
color: $gray-darkest; color: $gray-darkest;
background-color: $gray-light; background-color: $white-light;
&:hover, &:hover,
&:active, &:active,
...@@ -258,7 +258,6 @@ ...@@ -258,7 +258,6 @@
box-shadow: none; box-shadow: none;
border-color: lighten($blue-300, 20%); border-color: lighten($blue-300, 20%);
color: $gray-darkest; color: $gray-darkest;
background-color: $gray-light;
} }
} }
......
...@@ -453,6 +453,28 @@ span.idiff { ...@@ -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 { .md-previewer {
padding: $gl-padding; padding: $gl-padding;
} }
......
...@@ -42,8 +42,8 @@ ...@@ -42,8 +42,8 @@
} }
} }
.avatar { img.avatar {
margin-right: 15px; margin-right: $gl-padding;
} }
.controls { .controls {
......
...@@ -1008,6 +1008,10 @@ table.code { ...@@ -1008,6 +1008,10 @@ table.code {
display: block; display: block;
} }
} }
.note-edit-form {
margin-left: $note-icon-gutter-width;
}
} }
.discussion-body .image .frame { .discussion-body .image .frame {
......
...@@ -258,8 +258,15 @@ ul.related-merge-requests > li { ...@@ -258,8 +258,15 @@ ul.related-merge-requests > li {
} }
} }
.discussion-reply-holder .note-edit-form { .discussion-reply-holder {
display: block; .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 { .issue-sort-dropdown {
......
...@@ -59,6 +59,7 @@ ...@@ -59,6 +59,7 @@
border-radius: $border-radius-base; border-radius: $border-radius-base;
transition: border-color ease-in-out 0.15s, transition: border-color ease-in-out 0.15s,
box-shadow ease-in-out 0.15s; box-shadow ease-in-out 0.15s;
background-color: $white-light;
&.is-focused { &.is-focused {
@extend .form-control:focus; @extend .form-control:focus;
...@@ -173,6 +174,16 @@ ...@@ -173,6 +174,16 @@
.discussion-form { .discussion-form {
background-color: $white-light; background-color: $white-light;
@include media-breakpoint-down(xs) {
.user-avatar-link {
display: none;
}
.note-edit-form {
margin-left: 0;
}
}
} }
table { table {
...@@ -239,13 +250,25 @@ table { ...@@ -239,13 +250,25 @@ table {
.diff-file, .diff-file,
.commit-diff { .commit-diff {
.discussion-reply-holder { .discussion-reply-holder {
background-color: $white-light; background-color: $gray-light;
border-radius: 0 0 3px 3px; border-radius: 0 0 3px 3px;
padding: $gl-padding; padding: $gl-padding;
border-top: 1px solid $gray-100;
+ .new-note {
background-color: $gray-light;
border-top: 1px solid $gray-100;
}
&.is-replying { &.is-replying {
padding-bottom: $gl-padding; padding-bottom: $gl-padding;
} }
.user-avatar-link {
img {
margin-top: -3px;
}
}
} }
} }
......
...@@ -80,21 +80,17 @@ $note-form-margin-left: 72px; ...@@ -80,21 +80,17 @@ $note-form-margin-left: 72px;
} }
} }
li.note {
border-bottom: 1px solid $border-color;
}
.replies-toggle { .replies-toggle {
background-color: $gray-light; background-color: $gray-light;
padding: $gl-padding-8 $gl-padding; padding: $gl-padding-8 $gl-padding;
border-top: 1px solid $gray-100;
border-bottom: 1px solid $gray-100;
.collapse-replies-btn:hover { .collapse-replies-btn:hover {
color: $blue-600; color: $blue-600;
} }
&.expanded { &.expanded {
border-bottom: 1px solid $border-color;
span { span {
cursor: pointer; cursor: pointer;
} }
...@@ -211,8 +207,13 @@ $note-form-margin-left: 72px; ...@@ -211,8 +207,13 @@ $note-form-margin-left: 72px;
display: none; display: none;
} }
.user-avatar-link img {
margin-top: $gl-padding-8;
}
.note-edit-form { .note-edit-form {
display: block; display: block;
margin-left: 0;
&.current-note-edit-form + .note-awards { &.current-note-edit-form + .note-awards {
display: none; display: none;
...@@ -519,12 +520,30 @@ $note-form-margin-left: 72px; ...@@ -519,12 +520,30 @@ $note-form-margin-left: 72px;
} }
} }
.commit-diff { .code-commit .notes-content,
.notes-content { .diff-viewer > .image ~ .note-container {
background-color: $white-light; 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, .discussion-header,
.note-header-info { .note-header-info {
a { a {
......
...@@ -19,20 +19,24 @@ ...@@ -19,20 +19,24 @@
.discussion-reply-holder .discussion-reply-holder
- if can_create_note? - 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? - if discussion.potentially_resolvable?
- line_type = local_assigns.fetch(:line_type, nil) - line_type = local_assigns.fetch(:line_type, nil)
.btn-group.discussion-with-resolve-btn{ role: "group" } .discussion-with-resolve-btn
.btn-group{ role: "group" } .btn-group.discussion-with-resolve-btn{ role: "group" }
= link_to_reply_discussion(discussion, line_type) .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 .btn-group.discussion-actions
= render "discussions/new_issue_for_discussion", discussion: discussion, merge_request: discussion.noteable = render "discussions/new_issue_for_discussion", discussion: discussion, merge_request: discussion.noteable
= render "discussions/jump_to_next", discussion: discussion = render "discussions/jump_to_next", discussion: discussion
- else - else
= link_to_reply_discussion(discussion) .discussion-with-resolve-btn
= link_to_reply_discussion(discussion)
- elsif !current_user - elsif !current_user
.disabled-comment.text-center .disabled-comment.text-center
Please Please
......
/ Side-by-side diff view / Side-by-side diff view
.text-file{ data: diff_view_data } .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| - diff_file.parallel_diff_lines.each do |line|
- left = line[:left] - left = line[:left]
- right = line[:right] - right = line[:right]
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
.suppressed-container .suppressed-container
%a.show-suppressed-diff.cursor-pointer.js-show-suppressed-diff= _("Changes suppressed. Click to show.") %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", = render partial: "projects/diffs/line",
collection: diff_file.highlighted_diff_lines, collection: diff_file.highlighted_diff_lines,
as: :line, as: :line,
......
%inline-conflict-lines{ "inline-template" => "true", ":file" => "file" } %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" } %tr.line_holder.diff-inline{ "v-for" => "line in file.inlineLines" }
%td.diff-line-num.new_line{ ":class" => "lineCssClass(line)", "v-if" => "!line.isHeader" } %td.diff-line-num.new_line{ ":class" => "lineCssClass(line)", "v-if" => "!line.isHeader" }
%a {{line.new_line}} %a {{line.new_line}}
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
.note-header .note-header
.note-header-info .note-header-info
%a{ href: user_path(note.author) } %a{ href: user_path(note.author) }
%span.note-header-author-name %span.note-header-author-name.bold
= sanitize(note.author.name) = sanitize(note.author.name)
= user_status(note.author) = user_status(note.author)
%span.note-headline-light %span.note-headline-light
......
--- ---
title: Resolve Snippet icon button is misaligned title: Resolve Snippet icon button is misaligned
merge_request: 28522 merge_request: 28522
author: Marcel van Remmerden author:
type: other type: other
--- ---
title: Give New Snippet button green outline title: Give New Snippet button green outline
merge_request: 28559 merge_request: 28559
author: Marcel van Remmerden author:
type: other type: other
--- ---
title: Add hover and focus to Attach a file title: Add hover and focus to Attach a file
merge_request: 28682 merge_request: 28682
author: Marcel van Remmerden author:
type: fixed type: fixed
--- ---
title: Change collapse icon size to size of profile picture title: Change collapse icon size to size of profile picture
merge_request: 28512 merge_request: 28512
author: Marcel van Remmerden author:
type: other type: other
---
title: Implement borderless discussion design with new reply field
merge_request: 28580
author:
type: added
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