Commit e3bddb62 authored by Winnie Hellmann's avatar Winnie Hellmann
Browse files

Replace existing uses of timeline-entry with timeline entry component

parent 99862050
......@@ -4,6 +4,7 @@ import { mapActions, mapGetters, mapState } from 'vuex';
import _ from 'underscore';
import Autosize from 'autosize';
import { __, sprintf } from '~/locale';
import TimelineEntryItem from '~/vue_shared/components/notes/timeline_entry_item.vue';
import Flash from '../../flash';
import Autosave from '../../autosave';
import {
......@@ -30,6 +31,7 @@ export default {
markdownField,
userAvatarLink,
loadingButton,
TimelineEntryItem,
},
mixins: [issuableStateMixin],
props: {
......@@ -309,137 +311,135 @@ Please check your network connection and try again.`;
<div>
<note-signed-out-widget v-if="!isLoggedIn" />
<discussion-locked-widget v-else-if="!canCreateNote" :issuable-type="issuableTypeTitle" />
<div v-else-if="canCreateNote" class="notes notes-form timeline">
<div class="timeline-entry note-form">
<div class="timeline-entry-inner">
<div class="flash-container error-alert timeline-content"></div>
<div class="timeline-icon d-none d-sm-none d-md-block">
<user-avatar-link
v-if="author"
:link-href="author.path"
:img-src="author.avatar_url"
:img-alt="author.name"
:img-size="40"
/>
</div>
<div class="timeline-content timeline-content-form">
<form ref="commentForm" class="new-note common-note-form gfm-form js-main-target-form">
<div class="error-alert"></div>
<ul v-else-if="canCreateNote" class="notes notes-form timeline">
<timeline-entry-item class="note-form">
<div class="flash-container error-alert timeline-content"></div>
<div class="timeline-icon d-none d-sm-none d-md-block">
<user-avatar-link
v-if="author"
:link-href="author.path"
:img-src="author.avatar_url"
:img-alt="author.name"
:img-size="40"
/>
</div>
<div class="timeline-content timeline-content-form">
<form ref="commentForm" class="new-note common-note-form gfm-form js-main-target-form">
<div class="error-alert"></div>
<issue-warning
v-if="hasWarning(getNoteableData)"
:is-locked="isLocked(getNoteableData)"
:is-confidential="isConfidential(getNoteableData)"
/>
<issue-warning
v-if="hasWarning(getNoteableData)"
:is-locked="isLocked(getNoteableData)"
:is-confidential="isConfidential(getNoteableData)"
/>
<markdown-field
ref="markdownField"
:markdown-preview-path="markdownPreviewPath"
:markdown-docs-path="markdownDocsPath"
:quick-actions-docs-path="quickActionsDocsPath"
:markdown-version="markdownVersion"
:add-spacing-classes="false"
>
<textarea
id="note-body"
ref="textarea"
slot="textarea"
v-model="note"
:disabled="isSubmitting"
name="note[note]"
class="note-textarea js-vue-comment-form js-note-text
<markdown-field
ref="markdownField"
:markdown-preview-path="markdownPreviewPath"
:markdown-docs-path="markdownDocsPath"
:quick-actions-docs-path="quickActionsDocsPath"
:markdown-version="markdownVersion"
:add-spacing-classes="false"
>
<textarea
id="note-body"
ref="textarea"
slot="textarea"
v-model="note"
:disabled="isSubmitting"
name="note[note]"
class="note-textarea js-vue-comment-form js-note-text
js-gfm-input js-autosize markdown-area js-vue-textarea qa-comment-input"
data-supports-quick-actions="true"
aria-label="Description"
placeholder="Write a comment or drag your files here…"
@keydown.up="editCurrentUserLastNote();"
@keydown.meta.enter="handleSave();"
@keydown.ctrl.enter="handleSave();"
>
</textarea>
</markdown-field>
<div class="note-form-actions">
<div
class="float-left btn-group
data-supports-quick-actions="true"
aria-label="Description"
placeholder="Write a comment or drag your files here…"
@keydown.up="editCurrentUserLastNote();"
@keydown.meta.enter="handleSave();"
@keydown.ctrl.enter="handleSave();"
>
</textarea>
</markdown-field>
<div class="note-form-actions">
<div
class="float-left btn-group
append-right-10 comment-type-dropdown js-comment-type-dropdown droplab-dropdown"
>
<button
:disabled="isSubmitButtonDisabled"
class="btn btn-create comment-btn js-comment-button js-comment-submit-button
>
<button
:disabled="isSubmitButtonDisabled"
class="btn btn-create comment-btn js-comment-button js-comment-submit-button
qa-comment-button"
type="submit"
@click.prevent="handleSave();"
>
{{ __(commentButtonTitle) }}
</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);"
/>
type="submit"
@click.prevent="handleSave();"
>
{{ __(commentButtonTitle) }}
</button>
<button
v-if="note.length"
:disabled="isSubmitButtonDisabled"
name="button"
type="button"
class="btn btn-cancel js-note-discard"
@click="discard"
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"
>
Discard draft
<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>
</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>
</ul>
</div>
</template>
......@@ -6,6 +6,7 @@ import { truncateSha } from '~/lib/utils/text_utility';
import { s__, __, sprintf } from '~/locale';
import systemNote from '~/vue_shared/components/notes/system_note.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 { SYSTEM_NOTE } from '../constants';
import userAvatarLink from '../../vue_shared/components/user_avatar/user_avatar_link.vue';
......@@ -37,6 +38,7 @@ export default {
placeholderNote,
placeholderSystemNote,
systemNote,
TimelineEntryItem,
},
directives: {
GlTooltip: GlTooltipDirective,
......@@ -301,162 +303,156 @@ Please check your network connection and try again.`;
</script>
<template>
<li class="note note-discussion timeline-entry" :class="componentClassName">
<div class="timeline-entry-inner">
<div class="timeline-content">
<div :data-discussion-id="discussion.id" class="discussion js-discussion-container">
<div v-if="shouldRenderDiffs" class="discussion-header note-wrapper">
<div v-once class="timeline-icon">
<user-avatar-link
v-if="author"
:link-href="author.path"
:img-src="author.avatar_url"
:img-alt="author.name"
: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"
<timeline-entry-item class="note note-discussion" :class="componentClassName">
<div class="timeline-content">
<div :data-discussion-id="discussion.id" class="discussion js-discussion-container">
<div v-if="shouldRenderDiffs" class="discussion-header note-wrapper">
<div v-once class="timeline-icon">
<user-avatar-link
v-if="author"
:link-href="author.path"
:img-src="author.avatar_url"
:img-alt="author.name"
:img-size="40"
/>
</div>
<div v-if="shouldShowDiscussions" class="discussion-body">
<component
:is="wrapperComponent"
v-bind="wrapperComponentProps"
class="card discussion-wrapper"
>
<div class="discussion-notes">
<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
:is="componentName(note)"
v-for="note in replies"
:key="note.id"
:note="componentData(note)"
@handleDeleteNote="deleteNoteHandler"
/>
</template>
</template>
<template v-else>
<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 v-if="shouldShowDiscussions" class="discussion-body">
<component
:is="wrapperComponent"
v-bind="wrapperComponentProps"
class="card discussion-wrapper"
>
<div class="discussion-notes">
<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
:is="componentName(note)"
v-for="(note, index) in discussion.notes"
v-for="note in replies"
:key="note.id"
:note="componentData(note)"
@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">
</template>
<template v-else>
<component
:is="componentName(note)"
v-for="(note, index) in discussion.notes"
:key="note.id"
:note="componentData(note)"
@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
type="button"
class="js-vue-discussion-reply btn btn-text-field mr-sm-2 qa-discussion-reply"
title="Add a reply"
@click="showReplyForm"
class="btn btn-default mr-sm-2"
@click="resolveHandler();"
>
Reply...
<i v-if="isResolving" aria-hidden="true" class="fa fa-spinner fa-spin"></i>
{{ resolveButtonTitle }}
</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
type="button"
class="btn btn-default mr-sm-2"
@click="resolveHandler();"
v-gl-tooltip
class="btn btn-default discussion-next-btn"
title="Jump to next unresolved discussion"
@click="jumpToNextDiscussion"
>
<i
v-if="isResolving"
aria-hidden="true"
class="fa fa-spinner fa-spin"
></i>
{{ resolveButtonTitle }}
<icon name="comment-next" />
</button>
</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>
</template>
<note-form
v-if="isReplying"
ref="noteForm"
:discussion="discussion"
:is-editing="false"
save-button-title="Comment"
@handleFormUpdate="saveReply"
@cancelForm="cancelReplyForm"
/>
<note-signed-out-widget v-if="!canReply" />
</div>
</div>
</template>
<note-form
v-if="isReplying"
ref="noteForm"
:discussion="discussion"
:is-editing="false"
save-button-title="Comment"
@handleFormUpdate="saveReply"
@cancelForm="cancelReplyForm"
/>
<note-signed-out-widget v-if="!canReply" />
</div>
</component>
</div>
</div>
</component>
</div>
</div>
</div>
</li>
</timeline-entry-item>
</template>
......@@ -2,6 +2,7 @@
import $ from 'jquery';
import { mapGetters, mapActions } from 'vuex';
import { escape } from 'underscore';
import TimelineEntryItem from '~/vue_shared/components/notes/timeline_entry_item.vue';
import Flash from '../../flash';
import userAvatarLink from '../../vue_shared/components/user_avatar/user_avatar_link.vue';
import noteHeader from './note_header.vue';
......@@ -18,6 +19,7 @@ export default {
noteHeader,
noteActions,
noteBody,
TimelineEntryItem,
},
mixins: [noteable, resolvable],
props: {
......@@ -169,62 +171,60 @@ export default {
</script>