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
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"
......
......@@ -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"
......
......@@ -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>
......
......@@ -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>
......
......@@ -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,8 +400,16 @@ Please check your network connection and try again.`;
@resolve="resolveHandler"
@jumpToNextDiscussion="jumpToNextDiscussion"
/>
<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
v-if="isReplying"
ref="noteForm"
:discussion="discussion"
:is-editing="false"
......@@ -400,6 +420,7 @@ Please check your network connection and try again.`;
@handleFormUpdate="saveReply"
@cancelForm="cancelReplyForm"
/>
</div>
<note-signed-out-widget v-if="!userCanReply" />
</div>
</template>
......
......@@ -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>
......
......@@ -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;
}
}
......
......@@ -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;
}
......
......@@ -42,8 +42,8 @@
}
}
.avatar {
margin-right: 15px;
img.avatar {
margin-right: $gl-padding;
}
.controls {
......
......@@ -1008,6 +1008,10 @@ table.code {
display: block;
}
}
.note-edit-form {
margin-left: $note-icon-gutter-width;
}
}
.discussion-body .image .frame {
......
......@@ -258,8 +258,15 @@ ul.related-merge-requests > li {
}
}
.discussion-reply-holder .note-edit-form {
.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 {
......
......@@ -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;
}
}
}
}
......
......@@ -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,10 +520,28 @@ $note-form-margin-left: 72px;
}
}
.commit-diff {
.notes-content {
.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,
......
......@@ -19,9 +19,12 @@
.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)
.discussion-with-resolve-btn
.btn-group.discussion-with-resolve-btn{ role: "group" }
.btn-group{ role: "group" }
= link_to_reply_discussion(discussion, line_type)
......@@ -32,6 +35,7 @@
= render "discussions/new_issue_for_discussion", discussion: discussion, merge_request: discussion.noteable
= render "discussions/jump_to_next", discussion: discussion
- else
.discussion-with-resolve-btn
= link_to_reply_discussion(discussion)
- elsif !current_user
.disabled-comment.text-center
......
/ 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]
......
......@@ -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,
......
%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}}
......
......@@ -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
......
---
title: Resolve Snippet icon button is misaligned
merge_request: 28522
author: Marcel van Remmerden
author:
type: other
---
title: Give New Snippet button green outline
merge_request: 28559
author: Marcel van Remmerden
author:
type: other
---
title: Add hover and focus to Attach a file
merge_request: 28682
author: Marcel van Remmerden
author:
type: fixed
---
title: Change collapse icon size to size of profile picture
merge_request: 28512
author: Marcel van Remmerden
author:
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