Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Boxiang Sun
gitlab-ce
Commits
e3bddb62
Commit
e3bddb62
authored
Nov 29, 2018
by
Winnie Hellmann
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Replace existing uses of timeline-entry with timeline entry component
parent
99862050
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
371 additions
and
372 deletions
+371
-372
app/assets/javascripts/notes/components/comment_form.vue
app/assets/javascripts/notes/components/comment_form.vue
+121
-121
app/assets/javascripts/notes/components/noteable_discussion.vue
...sets/javascripts/notes/components/noteable_discussion.vue
+133
-137
app/assets/javascripts/notes/components/noteable_note.vue
app/assets/javascripts/notes/components/noteable_note.vue
+49
-49
app/assets/javascripts/vue_shared/components/notes/placeholder_note.vue
...ascripts/vue_shared/components/notes/placeholder_note.vue
+22
-22
app/assets/javascripts/vue_shared/components/notes/placeholder_system_note.vue
...s/vue_shared/components/notes/placeholder_system_note.vue
+9
-6
app/assets/javascripts/vue_shared/components/notes/skeleton_note.vue
...javascripts/vue_shared/components/notes/skeleton_note.vue
+8
-8
app/assets/javascripts/vue_shared/components/notes/system_note.vue
...s/javascripts/vue_shared/components/notes/system_note.vue
+25
-25
app/assets/javascripts/vue_shared/components/notes/timeline_entry_item.vue
...ripts/vue_shared/components/notes/timeline_entry_item.vue
+1
-1
spec/javascripts/vue_shared/components/notes/timeline_entry_item_spec.js
...s/vue_shared/components/notes/timeline_entry_item_spec.js
+3
-3
No files found.
app/assets/javascripts/notes/components/comment_form.vue
View file @
e3bddb62
...
@@ -4,6 +4,7 @@ import { mapActions, mapGetters, mapState } from 'vuex';
...
@@ -4,6 +4,7 @@ import { mapActions, mapGetters, mapState } from 'vuex';
import
_
from
'
underscore
'
;
import
_
from
'
underscore
'
;
import
Autosize
from
'
autosize
'
;
import
Autosize
from
'
autosize
'
;
import
{
__
,
sprintf
}
from
'
~/locale
'
;
import
{
__
,
sprintf
}
from
'
~/locale
'
;
import
TimelineEntryItem
from
'
~/vue_shared/components/notes/timeline_entry_item.vue
'
;
import
Flash
from
'
../../flash
'
;
import
Flash
from
'
../../flash
'
;
import
Autosave
from
'
../../autosave
'
;
import
Autosave
from
'
../../autosave
'
;
import
{
import
{
...
@@ -30,6 +31,7 @@ export default {
...
@@ -30,6 +31,7 @@ export default {
markdownField
,
markdownField
,
userAvatarLink
,
userAvatarLink
,
loadingButton
,
loadingButton
,
TimelineEntryItem
,
},
},
mixins
:
[
issuableStateMixin
],
mixins
:
[
issuableStateMixin
],
props
:
{
props
:
{
...
@@ -309,137 +311,135 @@ Please check your network connection and try again.`;
...
@@ -309,137 +311,135 @@ Please check your network connection and try again.`;
<div>
<div>
<note-signed-out-widget
v-if=
"!isLoggedIn"
/>
<note-signed-out-widget
v-if=
"!isLoggedIn"
/>
<discussion-locked-widget
v-else-if=
"!canCreateNote"
:issuable-type=
"issuableTypeTitle"
/>
<discussion-locked-widget
v-else-if=
"!canCreateNote"
:issuable-type=
"issuableTypeTitle"
/>
<div
v-else-if=
"canCreateNote"
class=
"notes notes-form timeline"
>
<ul
v-else-if=
"canCreateNote"
class=
"notes notes-form timeline"
>
<div
class=
"timeline-entry note-form"
>
<timeline-entry-item
class=
"note-form"
>
<div
class=
"timeline-entry-inner"
>
<div
class=
"flash-container error-alert timeline-content"
></div>
<div
class=
"flash-container error-alert timeline-content"
></div>
<div
class=
"timeline-icon d-none d-sm-none d-md-block"
>
<div
class=
"timeline-icon d-none d-sm-none d-md-block"
>
<user-avatar-link
<user-avatar-link
v-if=
"author"
v-if=
"author"
:link-href=
"author.path"
:link-href=
"author.path"
:img-src=
"author.avatar_url"
:img-src=
"author.avatar_url"
:img-alt=
"author.name"
:img-alt=
"author.name"
:img-size=
"40"
:img-size=
"40"
/>
/>
</div>
</div>
<div
class=
"timeline-content timeline-content-form"
>
<div
class=
"timeline-content timeline-content-form"
>
<form
ref=
"commentForm"
class=
"new-note common-note-form gfm-form js-main-target-form"
>
<form
ref=
"commentForm"
class=
"new-note common-note-form gfm-form js-main-target-form"
>
<div
class=
"error-alert"
></div>
<div
class=
"error-alert"
></div>
<issue-warning
<issue-warning
v-if=
"hasWarning(getNoteableData)"
v-if=
"hasWarning(getNoteableData)"
:is-locked=
"isLocked(getNoteableData)"
:is-locked=
"isLocked(getNoteableData)"
:is-confidential=
"isConfidential(getNoteableData)"
:is-confidential=
"isConfidential(getNoteableData)"
/>
/>
<markdown-field
<markdown-field
ref=
"markdownField"
ref=
"markdownField"
:markdown-preview-path=
"markdownPreviewPath"
:markdown-preview-path=
"markdownPreviewPath"
:markdown-docs-path=
"markdownDocsPath"
:markdown-docs-path=
"markdownDocsPath"
:quick-actions-docs-path=
"quickActionsDocsPath"
:quick-actions-docs-path=
"quickActionsDocsPath"
:markdown-version=
"markdownVersion"
:markdown-version=
"markdownVersion"
:add-spacing-classes=
"false"
:add-spacing-classes=
"false"
>
>
<textarea
<textarea
id=
"note-body"
id=
"note-body"
ref=
"textarea"
ref=
"textarea"
slot=
"textarea"
slot=
"textarea"
v-model=
"note"
v-model=
"note"
:disabled=
"isSubmitting"
:disabled=
"isSubmitting"
name=
"note[note]"
name=
"note[note]"
class=
"note-textarea js-vue-comment-form js-note-text
class=
"note-textarea js-vue-comment-form js-note-text
js-gfm-input js-autosize markdown-area js-vue-textarea qa-comment-input"
js-gfm-input js-autosize markdown-area js-vue-textarea qa-comment-input"
data-supports-quick-actions=
"true"
data-supports-quick-actions=
"true"
aria-label=
"Description"
aria-label=
"Description"
placeholder=
"Write a comment or drag your files here…"
placeholder=
"Write a comment or drag your files here…"
@
keydown.up=
"editCurrentUserLastNote();"
@
keydown.up=
"editCurrentUserLastNote();"
@
keydown.meta.enter=
"handleSave();"
@
keydown.meta.enter=
"handleSave();"
@
keydown.ctrl.enter=
"handleSave();"
@
keydown.ctrl.enter=
"handleSave();"
>
>
</textarea>
</textarea>
</markdown-field>
</markdown-field>
<div
class=
"note-form-actions"
>
<div
class=
"note-form-actions"
>
<div
<div
class=
"float-left btn-group
class=
"float-left btn-group
append-right-10 comment-type-dropdown js-comment-type-dropdown droplab-dropdown"
append-right-10 comment-type-dropdown js-comment-type-dropdown droplab-dropdown"
>
>
<button
<button
:disabled=
"isSubmitButtonDisabled"
:disabled=
"isSubmitButtonDisabled"
class=
"btn btn-create comment-btn js-comment-button js-comment-submit-button
class=
"btn btn-create comment-btn js-comment-button js-comment-submit-button
qa-comment-button"
qa-comment-button"
type=
"submit"
type=
"submit"
@
click.prevent=
"handleSave();"
@
click.prevent=
"handleSave();"
>
>
{{
__
(
commentButtonTitle
)
}}
{{
__
(
commentButtonTitle
)
}}
</button>
</button>
<button
:disabled=
"isSubmitButtonDisabled"
name=
"button"
type=
"button"
class=
"btn comment-btn note-type-toggle js-note-new-discussion dropdown-toggle qa-note-dropdown"
data-display=
"static"
data-toggle=
"dropdown"
aria-label=
"Open comment type dropdown"
>
<i
aria-hidden=
"true"
class=
"fa fa-caret-down toggle-icon"
>
</i>
</button>
<ul
class=
"note-type-dropdown dropdown-open-top dropdown-menu"
>
<li
:class=
"
{ 'droplab-item-selected': noteType === 'comment' }">
<button
type=
"button"
class=
"btn btn-transparent"
@
click.prevent=
"setNoteType('comment');"
>
<i
aria-hidden=
"true"
class=
"fa fa-check icon"
>
</i>
<div
class=
"description"
>
<strong>
Comment
</strong>
<p>
Add a general comment to this
{{
noteableDisplayName
}}
.
</p>
</div>
</button>
</li>
<li
class=
"divider droplab-item-ignore"
></li>
<li
:class=
"
{ 'droplab-item-selected': noteType === 'discussion' }">
<button
type=
"button"
class=
"btn btn-transparent qa-discussion-option"
@
click.prevent=
"setNoteType('discussion');"
>
<i
aria-hidden=
"true"
class=
"fa fa-check icon"
>
</i>
<div
class=
"description"
>
<strong>
Start discussion
</strong>
<p>
{{
startDiscussionDescription
}}
</p>
</div>
</button>
</li>
</ul>
</div>
<loading-button
v-if=
"canUpdateIssue"
:loading=
"isToggleStateButtonLoading"
:container-class=
"[
actionButtonClassNames,
'btn btn-comment btn-comment-and-close js-action-button',
]"
:disabled=
"isToggleStateButtonLoading || isSubmitting"
:label=
"issueActionButtonTitle"
@
click=
"handleSave(true);"
/>
<button
<button
v-if=
"note.length"
:disabled=
"isSubmitButtonDisabled"
name=
"button"
type=
"button"
type=
"button"
class=
"btn btn-cancel js-note-discard"
class=
"btn comment-btn note-type-toggle js-note-new-discussion dropdown-toggle qa-note-dropdown"
@
click=
"discard"
data-display=
"static"
data-toggle=
"dropdown"
aria-label=
"Open comment type dropdown"
>
>
Discard draft
<i
aria-hidden=
"true"
class=
"fa fa-caret-down toggle-icon"
>
</i>
</button>
</button>
<ul
class=
"note-type-dropdown dropdown-open-top dropdown-menu"
>
<li
:class=
"
{ 'droplab-item-selected': noteType === 'comment' }">
<button
type=
"button"
class=
"btn btn-transparent"
@
click.prevent=
"setNoteType('comment');"
>
<i
aria-hidden=
"true"
class=
"fa fa-check icon"
>
</i>
<div
class=
"description"
>
<strong>
Comment
</strong>
<p>
Add a general comment to this
{{
noteableDisplayName
}}
.
</p>
</div>
</button>
</li>
<li
class=
"divider droplab-item-ignore"
></li>
<li
:class=
"
{ 'droplab-item-selected': noteType === 'discussion' }">
<button
type=
"button"
class=
"btn btn-transparent qa-discussion-option"
@
click.prevent=
"setNoteType('discussion');"
>
<i
aria-hidden=
"true"
class=
"fa fa-check icon"
>
</i>
<div
class=
"description"
>
<strong>
Start discussion
</strong>
<p>
{{
startDiscussionDescription
}}
</p>
</div>
</button>
</li>
</ul>
</div>
</div>
</form>
</div>
<loading-button
v-if=
"canUpdateIssue"
:loading=
"isToggleStateButtonLoading"
:container-class=
"[
actionButtonClassNames,
'btn btn-comment btn-comment-and-close js-action-button',
]"
:disabled=
"isToggleStateButtonLoading || isSubmitting"
:label=
"issueActionButtonTitle"
@
click=
"handleSave(true);"
/>
<button
v-if=
"note.length"
type=
"button"
class=
"btn btn-cancel js-note-discard"
@
click=
"discard"
>
Discard draft
</button>
</div>
</form>
</div>
</div>
</
div
>
</
timeline-entry-item
>
</
div
>
</
ul
>
</div>
</div>
</
template
>
</
template
>
app/assets/javascripts/notes/components/noteable_discussion.vue
View file @
e3bddb62
...
@@ -6,6 +6,7 @@ import { truncateSha } from '~/lib/utils/text_utility';
...
@@ -6,6 +6,7 @@ import { truncateSha } from '~/lib/utils/text_utility';
import
{
s__
,
__
,
sprintf
}
from
'
~/locale
'
;
import
{
s__
,
__
,
sprintf
}
from
'
~/locale
'
;
import
systemNote
from
'
~/vue_shared/components/notes/system_note.vue
'
;
import
systemNote
from
'
~/vue_shared/components/notes/system_note.vue
'
;
import
icon
from
'
~/vue_shared/components/icon.vue
'
;
import
icon
from
'
~/vue_shared/components/icon.vue
'
;
import
TimelineEntryItem
from
'
~/vue_shared/components/notes/timeline_entry_item.vue
'
;
import
Flash
from
'
../../flash
'
;
import
Flash
from
'
../../flash
'
;
import
{
SYSTEM_NOTE
}
from
'
../constants
'
;
import
{
SYSTEM_NOTE
}
from
'
../constants
'
;
import
userAvatarLink
from
'
../../vue_shared/components/user_avatar/user_avatar_link.vue
'
;
import
userAvatarLink
from
'
../../vue_shared/components/user_avatar/user_avatar_link.vue
'
;
...
@@ -37,6 +38,7 @@ export default {
...
@@ -37,6 +38,7 @@ export default {
placeholderNote
,
placeholderNote
,
placeholderSystemNote
,
placeholderSystemNote
,
systemNote
,
systemNote
,
TimelineEntryItem
,
},
},
directives
:
{
directives
:
{
GlTooltip
:
GlTooltipDirective
,
GlTooltip
:
GlTooltipDirective
,
...
@@ -301,162 +303,156 @@ Please check your network connection and try again.`;
...
@@ -301,162 +303,156 @@ Please check your network connection and try again.`;
</
script
>
</
script
>
<
template
>
<
template
>
<li
class=
"note note-discussion timeline-entry"
:class=
"componentClassName"
>
<timeline-entry-item
class=
"note note-discussion"
:class=
"componentClassName"
>
<div
class=
"timeline-entry-inner"
>
<div
class=
"timeline-content"
>
<div
class=
"timeline-content"
>
<div
:data-discussion-id=
"discussion.id"
class=
"discussion js-discussion-container"
>
<div
:data-discussion-id=
"discussion.id"
class=
"discussion js-discussion-container"
>
<div
v-if=
"shouldRenderDiffs"
class=
"discussion-header note-wrapper"
>
<div
v-if=
"shouldRenderDiffs"
class=
"discussion-header note-wrapper"
>
<div
v-once
class=
"timeline-icon"
>
<div
v-once
class=
"timeline-icon"
>
<user-avatar-link
<user-avatar-link
v-if=
"author"
v-if=
"author"
:link-href=
"author.path"
:link-href=
"author.path"
:img-src=
"author.avatar_url"
:img-src=
"author.avatar_url"
:img-alt=
"author.name"
:img-alt=
"author.name"
:img-size=
"40"
:img-size=
"40"
/>
</div>
<note-header
:author=
"author"
:created-at=
"initialDiscussion.created_at"
:note-id=
"initialDiscussion.id"
:include-toggle=
"true"
:expanded=
"discussion.expanded"
@
toggleHandler=
"toggleDiscussionHandler"
>
<span
v-html=
"actionText"
></span>
</note-header>
<note-edited-text
v-if=
"discussion.resolved"
:edited-at=
"discussion.resolved_at"
:edited-by=
"discussion.resolved_by"
:action-text=
"resolvedText"
class-name=
"discussion-headline-light js-discussion-headline"
/>
<note-edited-text
v-else-if=
"lastUpdatedAt"
:edited-at=
"lastUpdatedAt"
:edited-by=
"lastUpdatedBy"
action-text=
"Last updated"
class-name=
"discussion-headline-light js-discussion-headline"
/>
/>
</div>
</div>
<div
v-if=
"shouldShowDiscussions"
class=
"discussion-body"
>
<note-header
<component
:author=
"author"
:is=
"wrapperComponent"
:created-at=
"initialDiscussion.created_at"
v-bind=
"wrapperComponentProps"
:note-id=
"initialDiscussion.id"
class=
"card discussion-wrapper"
:include-toggle=
"true"
>
:expanded=
"discussion.expanded"
<div
class=
"discussion-notes"
>
@
toggleHandler=
"toggleDiscussionHandler"
<ul
class=
"notes"
>
>
<template
v-if=
"shouldGroupReplies"
>
<span
v-html=
"actionText"
></span>
<component
</note-header>
:is=
"componentName(initialDiscussion)"
<note-edited-text
:note=
"componentData(initialDiscussion)"
v-if=
"discussion.resolved"
@
handleDeleteNote=
"deleteNoteHandler"
:edited-at=
"discussion.resolved_at"
>
:edited-by=
"discussion.resolved_by"
<slot
slot=
"avatar-badge"
name=
"avatar-badge"
></slot>
:action-text=
"resolvedText"
</component>
class-name=
"discussion-headline-light js-discussion-headline"
<toggle-replies-widget
/>
v-if=
"hasReplies"
<note-edited-text
:collapsed=
"isRepliesCollapsed"
v-else-if=
"lastUpdatedAt"
:replies=
"replies"
:edited-at=
"lastUpdatedAt"
@
toggle=
"toggleReplies"
:edited-by=
"lastUpdatedBy"
/>
action-text=
"Last updated"
<template
v-if=
"!isRepliesCollapsed"
>
class-name=
"discussion-headline-light js-discussion-headline"
<component
/>
:is=
"componentName(note)"
</div>
v-for=
"note in replies"
<div
v-if=
"shouldShowDiscussions"
class=
"discussion-body"
>
:key=
"note.id"
<component
:note=
"componentData(note)"
:is=
"wrapperComponent"
@
handleDeleteNote=
"deleteNoteHandler"
v-bind=
"wrapperComponentProps"
/>
class=
"card discussion-wrapper"
</
template
>
>
</template>
<div
class=
"discussion-notes"
>
<
template
v-else
>
<ul
class=
"notes"
>
<template
v-if=
"shouldGroupReplies"
>
<component
:is=
"componentName(initialDiscussion)"
:note=
"componentData(initialDiscussion)"
@
handleDeleteNote=
"deleteNoteHandler"
>
<slot
slot=
"avatar-badge"
name=
"avatar-badge"
></slot>
</component>
<toggle-replies-widget
v-if=
"hasReplies"
:collapsed=
"isRepliesCollapsed"
:replies=
"replies"
@
toggle=
"toggleReplies"
/>
<template
v-if=
"!isRepliesCollapsed"
>
<component
<component
:is=
"componentName(note)"
:is=
"componentName(note)"
v-for=
"
(note, index) in discussion.not
es"
v-for=
"
note in repli
es"
:key=
"note.id"
:key=
"note.id"
:note=
"componentData(note)"
:note=
"componentData(note)"
@
handleDeleteNote=
"deleteNoteHandler"
@
handleDeleteNote=
"deleteNoteHandler"
>
/>
<slot
v-if=
"index === 0"
slot=
"avatar-badge"
name=
"avatar-badge"
></slot>
</component>
</
template
>
</
template
>
</ul>
</template>
<div
<
template
v-else
>
v-if=
"!isRepliesCollapsed"
<component
:class=
"{ 'is-replying': isReplying }"
:is=
"componentName(note)"
class=
"discussion-reply-holder"
v-for=
"(note, index) in discussion.notes"
>
:key=
"note.id"
<
template
v-if=
"!isReplying && canReply"
>
:note=
"componentData(note)"
<div
class=
"discussion-with-resolve-btn"
>
@
handleDeleteNote=
"deleteNoteHandler"
>
<slot
v-if=
"index === 0"
slot=
"avatar-badge"
name=
"avatar-badge"
></slot>
</component>
</
template
>
</ul>
<div
v-if=
"!isRepliesCollapsed"
:class=
"{ 'is-replying': isReplying }"
class=
"discussion-reply-holder"
>
<
template
v-if=
"!isReplying && canReply"
>
<div
class=
"discussion-with-resolve-btn"
>
<button
type=
"button"
class=
"js-vue-discussion-reply btn btn-text-field mr-sm-2 qa-discussion-reply"
title=
"Add a reply"
@
click=
"showReplyForm"
>
Reply...
</button>
<div
v-if=
"discussion.resolvable"
>
<button
<button
type=
"button"
type=
"button"
class=
"js-vue-discussion-reply btn btn-text-field mr-sm-2 qa-discussion-reply"
class=
"btn btn-default mr-sm-2"
title=
"Add a reply"
@
click=
"resolveHandler();"
@
click=
"showReplyForm"
>
>
Reply...
<i
v-if=
"isResolving"
aria-hidden=
"true"
class=
"fa fa-spinner fa-spin"
></i>
{{
resolveButtonTitle
}}
</button>
</button>
<div
v-if=
"discussion.resolvable"
>
</div>
<div
v-if=
"discussion.resolvable"
class=
"btn-group discussion-actions ml-sm-2"
role=
"group"
>
<div
v-if=
"!discussionResolved"
class=
"btn-group"
role=
"group"
>
<a
v-gl-tooltip
:href=
"discussion.resolve_with_issue_path"
:title=
"s__('MergeRequests|Resolve this discussion in a new issue')"
class=
"new-issue-for-discussion btn btn-default discussion-create-issue-btn"
>
<icon
name=
"issue-new"
/>
</a>
</div>
<div
v-if=
"hasUnresolvedDiscussions"
class=
"btn-group"
role=
"group"
>
<button
<button
type=
"button"
v-gl-tooltip
class=
"btn btn-default mr-sm-2"
class=
"btn btn-default discussion-next-btn"
@
click=
"resolveHandler();"
title=
"Jump to next unresolved discussion"
@
click=
"jumpToNextDiscussion"
>
>
<i
<icon
name=
"comment-next"
/>
v-if=
"isResolving"
aria-hidden=
"true"
class=
"fa fa-spinner fa-spin"
></i>
{{
resolveButtonTitle
}}
</button>
</button>
</div>
</div>
<div
v-if=
"discussion.resolvable"
class=
"btn-group discussion-actions ml-sm-2"
role=
"group"
>
<div
v-if=
"!discussionResolved"
class=
"btn-group"
role=
"group"
>
<a
v-gl-tooltip
:href=
"discussion.resolve_with_issue_path"
:title=
"s__('MergeRequests|Resolve this discussion in a new issue')"
class=
"new-issue-for-discussion btn btn-default discussion-create-issue-btn"
>
<icon
name=
"issue-new"
/>
</a>
</div>
<div
v-if=
"hasUnresolvedDiscussions"
class=
"btn-group"
role=
"group"
>
<button
v-gl-tooltip
class=
"btn btn-default discussion-next-btn"
title=
"Jump to next unresolved discussion"
@
click=
"jumpToNextDiscussion"
>
<icon
name=
"comment-next"
/>
</button>
</div>
</div>
</div>
</div>
</
template
>
</
div
>
<note-form
</
template
>
v-if=
"isReplying"
<note-form
ref=
"noteForm
"
v-if=
"isReplying
"
:discussion=
"discussion
"
ref=
"noteForm
"
:is-editing=
"false
"
:discussion=
"discussion
"
save-button-title=
"Comment
"
:is-editing=
"false
"
@
handleFormUpdate=
"saveReply
"
save-button-title=
"Comment
"
@
cancelForm=
"cancelReplyForm
"
@
handleFormUpdate=
"saveReply
"
/>
@
cancelForm=
"cancelReplyForm"
<note-signed-out-widget
v-if=
"!canReply"
/>
/>
<
/div
>
<
note-signed-out-widget
v-if=
"!canReply"
/
>
</div>
</div>
</
component
>
</
div
>
</
div
>
</
component
>
</div>
</div>
</div>
</div>
</div>
</div>
</
li
>
</
timeline-entry-item
>
</template>
</template>
app/assets/javascripts/notes/components/noteable_note.vue
View file @
e3bddb62
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
import
$
from
'
jquery
'
;
import
$
from
'
jquery
'
;
import
{
mapGetters
,
mapActions
}
from
'
vuex
'
;
import
{
mapGetters
,
mapActions
}
from
'
vuex
'
;
import
{
escape
}
from
'
underscore
'
;
import
{
escape
}
from
'
underscore
'
;
import
TimelineEntryItem
from
'
~/vue_shared/components/notes/timeline_entry_item.vue
'
;
import
Flash
from
'
../../flash
'
;
import
Flash
from
'
../../flash
'
;
import
userAvatarLink
from
'
../../vue_shared/components/user_avatar/user_avatar_link.vue
'
;
import
userAvatarLink
from
'
../../vue_shared/components/user_avatar/user_avatar_link.vue
'
;
import
noteHeader
from
'
./note_header.vue
'
;
import
noteHeader
from
'
./note_header.vue
'
;
...
@@ -18,6 +19,7 @@ export default {
...
@@ -18,6 +19,7 @@ export default {
noteHeader
,
noteHeader
,
noteActions
,
noteActions
,
noteBody
,
noteBody
,
TimelineEntryItem
,
},
},
mixins
:
[
noteable
,
resolvable
],
mixins
:
[
noteable
,
resolvable
],
props
:
{
props
:
{
...
@@ -169,62 +171,60 @@ export default {
...
@@ -169,62 +171,60 @@ export default {
</
script
>
</
script
>
<
template
>
<
template
>
<
li
<
timeline-entry-item
:id=
"noteAnchorId"
:id=
"noteAnchorId"
:class=
"classNameBindings"
:class=
"classNameBindings"
:data-award-url=
"note.toggle_award_path"
:data-award-url=
"note.toggle_award_path"
:data-note-id=
"note.id"
:data-note-id=
"note.id"
class=
"note
timeline-entry
note-wrapper"
class=
"note note-wrapper"
>
>
<div
class=
"timeline-entry-inner"
>
<div
v-once
class=
"timeline-icon"
>
<div
v-once
class=
"timeline-icon"
>
<user-avatar-link
<user-avatar-link
:link-href=
"author.path"
:link-href=
"author.path"
:img-src=
"author.avatar_url"
:img-src=
"author.avatar_url"
:img-alt=
"author.name"
:img-alt=
"author.name"
:img-size=
"40"
:img-size=
"40"
>
>
<slot
slot=
"avatar-badge"
name=
"avatar-badge"
>
</slot>
<slot
slot=
"avatar-badge"
name=
"avatar-badge"
>
</slot>
</user-avatar-link>
</user-avatar-link>
</div>
</div>
<div
class=
"timeline-content"
>
<div
class=
"timeline-content"
>
<div
class=
"note-header"
>
<div
class=
"note-header"
>
<note-header
<note-header
v-once
v-once
:author=
"author"
:author=
"author"
:created-at=
"note.created_at"
:created-at=
"note.created_at"
:note-id=
"note.id"
:note-id=
"note.id"
action-text=
"commented"
action-text=
"commented"
/>
/>
<note-actions
<note-actions
:author-id=
"author.id"
:author-id=
"author.id"
:note-id=
"note.id"
:note-id=
"note.id"
:note-url=
"note.noteable_note_url"
:note-url=
"note.noteable_note_url"
:access-level=
"note.human_access"
:access-level=
"note.human_access"
:can-edit=
"note.current_user.can_edit"
:can-award-emoji=
"note.current_user.can_award_emoji"
:can-delete=
"note.current_user.can_edit"
:can-report-as-abuse=
"canReportAsAbuse"
:can-resolve=
"note.current_user.can_resolve"
:report-abuse-path=
"note.report_abuse_path"
:resolvable=
"note.resolvable"
:is-resolved=
"note.resolved"
:is-resolving=
"isResolving"
:resolved-by=
"note.resolved_by"
@
handleEdit=
"editHandler"
@
handleDelete=
"deleteHandler"
@
handleResolve=
"resolveHandler"
/>
</div>
<note-body
ref=
"noteBody"
:note=
"note"
:can-edit=
"note.current_user.can_edit"
:can-edit=
"note.current_user.can_edit"
:is-editing=
"isEditing"
:can-award-emoji=
"note.current_user.can_award_emoji"
@
handleFormUpdate=
"formUpdateHandler"
:can-delete=
"note.current_user.can_edit"
@
cancelForm=
"formCancelHandler"
:can-report-as-abuse=
"canReportAsAbuse"
:can-resolve=
"note.current_user.can_resolve"
:report-abuse-path=
"note.report_abuse_path"
:resolvable=
"note.resolvable"
:is-resolved=
"note.resolved"
:is-resolving=
"isResolving"
:resolved-by=
"note.resolved_by"
@
handleEdit=
"editHandler"
@
handleDelete=
"deleteHandler"
@
handleResolve=
"resolveHandler"
/>
/>
</div>
</div>
<note-body
ref=
"noteBody"
:note=
"note"
:can-edit=
"note.current_user.can_edit"
:is-editing=
"isEditing"
@
handleFormUpdate=
"formUpdateHandler"
@
cancelForm=
"formCancelHandler"
/>
</div>
</div>
</
li
>
</
timeline-entry-item
>
</
template
>
</
template
>
app/assets/javascripts/vue_shared/components/notes/placeholder_note.vue
View file @
e3bddb62
...
@@ -17,12 +17,14 @@
...
@@ -17,12 +17,14 @@
* />
* />
*/
*/
import
{
mapGetters
}
from
'
vuex
'
;
import
{
mapGetters
}
from
'
vuex
'
;
import
TimelineEntryItem
from
'
~/vue_shared/components/notes/timeline_entry_item.vue
'
;
import
userAvatarLink
from
'
../user_avatar/user_avatar_link.vue
'
;
import
userAvatarLink
from
'
../user_avatar/user_avatar_link.vue
'
;
export
default
{
export
default
{
name
:
'
PlaceholderNote
'
,
name
:
'
PlaceholderNote
'
,
components
:
{
components
:
{
userAvatarLink
,
userAvatarLink
,
TimelineEntryItem
,
},
},
props
:
{
props
:
{
note
:
{
note
:
{
...
@@ -37,30 +39,28 @@ export default {
...
@@ -37,30 +39,28 @@ export default {
</
script
>
</
script
>
<
template
>
<
template
>
<li
class=
"note being-posted fade-in-half timeline-entry"
>
<timeline-entry-item
class=
"note being-posted fade-in-half"
>
<div
class=
"timeline-entry-inner"
>
<div
class=
"timeline-icon"
>
<div
class=
"timeline-icon"
>
<user-avatar-link
<user-avatar-link
:link-href=
"getUserData.path"
:link-href=
"getUserData.path"
:img-src=
"getUserData.avatar_url"
:img-src=
"getUserData.avatar_url"
:img-size=
"40"
:img-size=
"40"
/>
/>
</div>
</div>
<div
:class=
"
{ discussion: !note.individual_note }" class="timeline-content">
<div
:class=
"
{ discussion: !note.individual_note }" class="timeline-content">
<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"
>
{{
getUserData
.
name
}}
</span>
<span
class=
"note-headline-light"
>
@
{{
getUserData
.
username
}}
</span>
<span
class=
"note-headline-light"
>
@
{{
getUserData
.
username
}}
</span>
</a>
</a>
</div>
</div>
</div>
<div
class=
"note-body"
>
</div
>
<div
class=
"note-text
"
>
<div
class=
"note-body
"
>
<p>
{{
note
.
body
}}
</p
>
<div
class=
"note-text"
>
<
/div
>
<
p>
{{
note
.
body
}}
</p
>
</div>
</div>
</div>
</div>
</div>
</div>
</
li
>
</
timeline-entry-item
>
</
template
>
</
template
>
app/assets/javascripts/vue_shared/components/notes/placeholder_system_note.vue
View file @
e3bddb62
<
script
>
<
script
>
import
TimelineEntryItem
from
'
~/vue_shared/components/notes/timeline_entry_item.vue
'
;
/**
/**
* Common component to render a placeholder system note.
* Common component to render a placeholder system note.
*
*
...
@@ -9,6 +11,9 @@
...
@@ -9,6 +11,9 @@
*/
*/
export
default
{
export
default
{
name
:
'
PlaceholderSystemNote
'
,
name
:
'
PlaceholderSystemNote
'
,
components
:
{
TimelineEntryItem
,
},
props
:
{
props
:
{
note
:
{
note
:
{
type
:
Object
,
type
:
Object
,
...
@@ -19,11 +24,9 @@ export default {
...
@@ -19,11 +24,9 @@ export default {
</
script
>
</
script
>
<
template
>
<
template
>
<li
class=
"note system-note timeline-entry being-posted fade-in-half"
>
<timeline-entry-item
class=
"note system-note being-posted fade-in-half"
>
<div
class=
"timeline-entry-inner"
>
<div
class=
"timeline-content"
>
<div
class=
"timeline-content"
>
<em>
{{
note
.
body
}}
</em>
<em>
{{
note
.
body
}}
</em>
</div>
</div>
</div>
</
li
>
</
timeline-entry-item
>
</
template
>
</
template
>
app/assets/javascripts/vue_shared/components/notes/skeleton_note.vue
View file @
e3bddb62
<
script
>
<
script
>
import
{
GlSkeletonLoading
}
from
'
@gitlab/ui
'
;
import
{
GlSkeletonLoading
}
from
'
@gitlab/ui
'
;
import
TimelineEntryItem
from
'
~/vue_shared/components/notes/timeline_entry_item.vue
'
;
export
default
{
export
default
{
name
:
'
SkeletonNote
'
,
name
:
'
SkeletonNote
'
,
components
:
{
components
:
{
GlSkeletonLoading
,
GlSkeletonLoading
,
TimelineEntryItem
,
},
},
};
};
</
script
>
</
script
>
<
template
>
<
template
>
<li
class=
"timeline-entry note note-wrapper"
>
<timeline-entry-item
class=
"note note-wrapper"
>
<div
class=
"timeline-entry-inner"
>
<div
class=
"timeline-icon"
></div>
<div
class=
"timeline-icon"
></div>
<div
class=
"timeline-content"
>
<div
class=
"timeline-content"
>
<div
class=
"note-header"
></div>
<div
class=
"note-header"
></div>
<div
class=
"note-body"
><gl-skeleton-loading
/></div>
<div
class=
"note-body"
><gl-skeleton-loading
/></div>
</div>
</div>
</div>
</
li
>
</
timeline-entry-item
>
</
template
>
</
template
>
app/assets/javascripts/vue_shared/components/notes/system_note.vue
View file @
e3bddb62
...
@@ -20,6 +20,7 @@ import $ from 'jquery';
...
@@ -20,6 +20,7 @@ import $ from 'jquery';
import
{
mapGetters
}
from
'
vuex
'
;
import
{
mapGetters
}
from
'
vuex
'
;
import
noteHeader
from
'
~/notes/components/note_header.vue
'
;
import
noteHeader
from
'
~/notes/components/note_header.vue
'
;
import
Icon
from
'
~/vue_shared/components/icon.vue
'
;
import
Icon
from
'
~/vue_shared/components/icon.vue
'
;
import
TimelineEntryItem
from
'
./timeline_entry_item.vue
'
;
import
{
spriteIcon
}
from
'
../../../lib/utils/common_utils
'
;
import
{
spriteIcon
}
from
'
../../../lib/utils/common_utils
'
;
const
MAX_VISIBLE_COMMIT_LIST_COUNT
=
3
;
const
MAX_VISIBLE_COMMIT_LIST_COUNT
=
3
;
...
@@ -29,6 +30,7 @@ export default {
...
@@ -29,6 +30,7 @@ export default {
components
:
{
components
:
{
Icon
,
Icon
,
noteHeader
,
noteHeader
,
TimelineEntryItem
,
},
},
props
:
{
props
:
{
note
:
{
note
:
{
...
@@ -73,36 +75,34 @@ export default {
...
@@ -73,36 +75,34 @@ export default {
</
script
>
</
script
>
<
template
>
<
template
>
<
li
<
timeline-entry-item
:id=
"noteAnchorId"
:id=
"noteAnchorId"
:class=
"
{ target: isTargetNote }"
:class=
"
{ target: isTargetNote }"
class="note system-note
timeline-entry
note-wrapper"
class="note system-note note-wrapper"
>
>
<div
class=
"timeline-entry-inner"
>
<div
class=
"timeline-icon"
v-html=
"iconHtml"
></div>
<div
class=
"timeline-icon"
v-html=
"iconHtml"
></div>
<div
class=
"timeline-content"
>
<div
class=
"timeline-content"
>
<div
class=
"note-header"
>
<div
class=
"note-header"
>
<note-header
:author=
"note.author"
:created-at=
"note.created_at"
:note-id=
"note.id"
>
<note-header
:author=
"note.author"
:created-at=
"note.created_at"
:note-id=
"note.id"
>
<span
v-html=
"actionTextHtml"
></span>
<span
v-html=
"actionTextHtml"
></span>
</note-header>
</note-header>
</div>
</div>
<div
class=
"note-body"
>
<div
class=
"note-body"
>
<div
<div
:class=
"
{
:class=
"
{
'system-note-commit-list': hasMoreCommits,
'system-note-commit-list': hasMoreCommits,
'hide-shade': expanded,
'hide-shade': expanded,
}"
}"
class="note-text"
class="note-text"
v-html="note.note_html"
v-html="note.note_html"
>
</div>
>
</div>
<div
v-if=
"hasMoreCommits"
class=
"flex-list"
>
<div
v-if=
"hasMoreCommits"
class=
"flex-list"
>
<div
class=
"system-note-commit-list-toggler flex-row"
@
click=
"expanded = !expanded;"
>
<div
class=
"system-note-commit-list-toggler flex-row"
@
click=
"expanded = !expanded;"
>
<icon
:name=
"toggleIcon"
:size=
"8"
class=
"append-right-5"
/>
<icon
:name=
"toggleIcon"
:size=
"8"
class=
"append-right-5"
/>
<span>
Toggle commit list
</span>
<span>
Toggle commit list
</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</
li
>
</
timeline-entry-item
>
</
template
>
</
template
>
app/assets/javascripts/vue_shared/components/notes/timeline_entry_item.vue
View file @
e3bddb62
<
script
>
<
script
>
export
default
{
export
default
{
name
:
'
TimelineEntry
'
,
name
:
'
TimelineEntry
Item
'
,
};
};
</
script
>
</
script
>
...
...
spec/javascripts/vue_shared/components/notes/timeline_entry_item_spec.js
View file @
e3bddb62
import
{
shallowMount
,
createLocalVue
}
from
'
@vue/test-utils
'
;
import
{
shallowMount
,
createLocalVue
}
from
'
@vue/test-utils
'
;
import
TimelineEntry
from
'
~/vue_shared/components/notes/timeline_entry
.vue
'
;
import
TimelineEntry
Item
from
'
~/vue_shared/components/notes/timeline_entry_item
.vue
'
;
describe
(
TimelineEntry
.
name
,
()
=>
{
describe
(
TimelineEntry
Item
.
name
,
()
=>
{
let
wrapper
;
let
wrapper
;
const
factory
=
(
options
=
{})
=>
{
const
factory
=
(
options
=
{})
=>
{
const
localVue
=
createLocalVue
();
const
localVue
=
createLocalVue
();
wrapper
=
shallowMount
(
TimelineEntry
,
{
wrapper
=
shallowMount
(
TimelineEntry
Item
,
{
localVue
,
localVue
,
...
options
,
...
options
,
});
});
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment