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
1
Merge Requests
1
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
nexedi
gitlab-ce
Commits
0496b76b
Commit
0496b76b
authored
May 07, 2020
by
Natalia Tepluhina
Committed by
Illya Klymov
May 07, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Resolve "Design Comment: Edit Comment text"
parent
76a8a8c7
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
376 additions
and
97 deletions
+376
-97
app/assets/javascripts/design_management/components/design_notes/design_discussion.vue
..._management/components/design_notes/design_discussion.vue
+7
-1
app/assets/javascripts/design_management/components/design_notes/design_note.vue
...design_management/components/design_notes/design_note.vue
+100
-20
app/assets/javascripts/design_management/components/design_notes/design_reply_form.vue
..._management/components/design_notes/design_reply_form.vue
+38
-6
app/assets/javascripts/design_management/graphql/mutations/update_note.mutation.graphql
...management/graphql/mutations/update_note.mutation.graphql
+10
-0
app/assets/javascripts/design_management/pages/design/index.vue
...sets/javascripts/design_management/pages/design/index.vue
+6
-1
app/assets/javascripts/design_management/utils/cache_update.js
...ssets/javascripts/design_management/utils/cache_update.js
+1
-1
app/assets/javascripts/design_management/utils/error_messages.js
...ets/javascripts/design_management/utils/error_messages.js
+2
-0
changelogs/unreleased/118609-design-comment-edit-comment-text.yml
...gs/unreleased/118609-design-comment-edit-comment-text.yml
+5
-0
locale/gitlab.pot
locale/gitlab.pot
+21
-0
spec/frontend/design_management/components/design_notes/__snapshots__/design_note_spec.js.snap
...nents/design_notes/__snapshots__/design_note_spec.js.snap
+44
-39
spec/frontend/design_management/components/design_notes/__snapshots__/design_reply_form_spec.js.snap
...design_notes/__snapshots__/design_reply_form_spec.js.snap
+15
-0
spec/frontend/design_management/components/design_notes/design_note_spec.js
...gn_management/components/design_notes/design_note_spec.js
+82
-24
spec/frontend/design_management/components/design_notes/design_reply_form_spec.js
...agement/components/design_notes/design_reply_form_spec.js
+45
-5
No files found.
app/assets/javascripts/design_management/components/design_notes/design_discussion.vue
View file @
0496b76b
...
@@ -103,7 +103,13 @@ export default {
...
@@ -103,7 +103,13 @@ export default {
class=
"design-discussion bordered-box position-relative"
class=
"design-discussion bordered-box position-relative"
data-qa-selector=
"design_discussion_content"
data-qa-selector=
"design_discussion_content"
>
>
<design-note
v-for=
"note in discussion.notes"
:key=
"note.id"
:note=
"note"
/>
<design-note
v-for=
"note in discussion.notes"
:key=
"note.id"
:note=
"note"
:markdown-preview-path=
"markdownPreviewPath"
@
error=
"$emit('updateNoteError', $event)"
/>
<div
class=
"reply-wrapper"
>
<div
class=
"reply-wrapper"
>
<reply-placeholder
<reply-placeholder
v-if=
"!isFormRendered"
v-if=
"!isFormRendered"
...
...
app/assets/javascripts/design_management/components/design_notes/design_note.vue
View file @
0496b76b
<
script
>
<
script
>
import
{
ApolloMutation
}
from
'
vue-apollo
'
;
import
{
GlTooltipDirective
,
GlIcon
}
from
'
@gitlab/ui
'
;
import
updateNoteMutation
from
'
../../graphql/mutations/update_note.mutation.graphql
'
;
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
TimelineEntryItem
from
'
~/vue_shared/components/notes/timeline_entry_item.vue
'
;
import
TimelineEntryItem
from
'
~/vue_shared/components/notes/timeline_entry_item.vue
'
;
import
TimeAgoTooltip
from
'
~/vue_shared/components/time_ago_tooltip.vue
'
;
import
TimeAgoTooltip
from
'
~/vue_shared/components/time_ago_tooltip.vue
'
;
import
DesignReplyForm
from
'
./design_reply_form.vue
'
;
import
{
findNoteId
}
from
'
../../utils/design_management_utils
'
;
import
{
findNoteId
}
from
'
../../utils/design_management_utils
'
;
import
{
hasErrors
}
from
'
../../utils/cache_update
'
;
export
default
{
export
default
{
components
:
{
components
:
{
UserAvatarLink
,
UserAvatarLink
,
TimelineEntryItem
,
TimelineEntryItem
,
TimeAgoTooltip
,
TimeAgoTooltip
,
DesignReplyForm
,
ApolloMutation
,
GlIcon
,
},
directives
:
{
GlTooltip
:
GlTooltipDirective
,
},
},
props
:
{
props
:
{
note
:
{
note
:
{
type
:
Object
,
type
:
Object
,
required
:
true
,
required
:
true
,
},
},
markdownPreviewPath
:
{
type
:
String
,
required
:
false
,
default
:
''
,
},
},
data
()
{
return
{
noteText
:
this
.
note
.
body
,
isEditing
:
false
,
};
},
},
computed
:
{
computed
:
{
author
()
{
author
()
{
...
@@ -26,12 +48,31 @@ export default {
...
@@ -26,12 +48,31 @@ export default {
isNoteLinked
()
{
isNoteLinked
()
{
return
this
.
$route
.
hash
===
`#note_
${
this
.
noteAnchorId
}
`
;
return
this
.
$route
.
hash
===
`#note_
${
this
.
noteAnchorId
}
`
;
},
},
mutationPayload
()
{
return
{
id
:
this
.
note
.
id
,
body
:
this
.
noteText
,
};
},
},
},
mounted
()
{
mounted
()
{
if
(
this
.
isNoteLinked
)
{
if
(
this
.
isNoteLinked
)
{
this
.
$refs
.
anchor
.
$el
.
scrollIntoView
({
behavior
:
'
smooth
'
,
inline
:
'
start
'
});
this
.
$refs
.
anchor
.
$el
.
scrollIntoView
({
behavior
:
'
smooth
'
,
inline
:
'
start
'
});
}
}
},
},
methods
:
{
hideForm
()
{
this
.
isEditing
=
false
;
this
.
noteText
=
this
.
note
.
body
;
},
onDone
({
data
})
{
this
.
hideForm
();
if
(
hasErrors
(
data
.
updateNote
))
{
this
.
$emit
(
'
error
'
,
data
.
errors
[
0
]);
}
},
},
updateNoteMutation
,
};
};
</
script
>
</
script
>
...
@@ -43,26 +84,65 @@ export default {
...
@@ -43,26 +84,65 @@ export default {
:img-alt=
"author.username"
:img-alt=
"author.username"
:img-size=
"40"
:img-size=
"40"
/>
/>
<a
<div
class=
"d-flex justify-content-between"
>
v-once
<div>
:href=
"author.webUrl"
<a
class=
"js-user-link"
v-once
:data-user-id=
"author.id"
:href=
"author.webUrl"
:data-username=
"author.username"
class=
"js-user-link"
>
:data-user-id=
"author.id"
<span
class=
"note-header-author-name bold"
>
{{
author
.
name
}}
</span>
:data-username=
"author.username"
<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-header-author-name bold"
>
{{
author
.
name
}}
</span>
</a>
<span
v-if=
"author.status_tooltip_html"
v-html=
"author.status_tooltip_html"
></span>
<span
class=
"note-headline-light note-headline-meta"
>
<span
class=
"note-headline-light"
>
@
{{
author
.
username
}}
</span>
<span
class=
"system-note-message"
>
<slot></slot>
</span>
<template
v-if=
"note.createdAt"
>
<span
class=
"system-note-separator"
></span>
<a
class=
"note-timestamp system-note-separator"
:href=
"`#note_$
{noteAnchorId}`">
<time-ago-tooltip
:time=
"note.createdAt"
tooltip-placement=
"bottom"
/>
</a>
</a>
</
template
>
<span
class=
"note-headline-light note-headline-meta"
>
</span>
<span
class=
"system-note-message"
>
<slot></slot>
</span>
<div
class=
"note-text md"
data-qa-selector=
"note_content"
v-html=
"note.bodyHtml"
></div>
<template
v-if=
"note.createdAt"
>
<span
class=
"system-note-separator"
></span>
<a
class=
"note-timestamp system-note-separator"
:href=
"`#note_$
{noteAnchorId}`">
<time-ago-tooltip
:time=
"note.createdAt"
tooltip-placement=
"bottom"
/>
</a>
</
template
>
</span>
</div>
<button
v-if=
"!isEditing"
v-gl-tooltip
type=
"button"
title=
"Edit comment"
class=
"note-action-button js-note-edit btn btn-transparent qa-note-edit-button"
@
click=
"isEditing = true"
>
<gl-icon
name=
"pencil"
class=
"link-highlight"
/>
</button>
</div>
<div
v-if=
"!isEditing"
class=
"note-text js-note-text md"
data-qa-selector=
"note_content"
v-html=
"note.bodyHtml"
></div>
<apollo-mutation
v-else
#default=
"{ mutate, loading }"
:mutation=
"$options.updateNoteMutation"
:variables=
"{
input: mutationPayload,
}"
@
error=
"$emit('error', $event)"
@
done=
"onDone"
>
<design-reply-form
v-model=
"noteText"
:is-saving=
"loading"
:markdown-preview-path=
"markdownPreviewPath"
:is-new-comment=
"false"
class=
"mt-5"
@
submitForm=
"mutate"
@
cancelForm=
"hideForm"
/>
</apollo-mutation>
</timeline-entry-item>
</timeline-entry-item>
</template>
</template>
app/assets/javascripts/design_management/components/design_notes/design_reply_form.vue
View file @
0496b76b
<
script
>
<
script
>
import
{
GlDeprecatedButton
,
GlModal
}
from
'
@gitlab/ui
'
;
import
{
GlDeprecatedButton
,
GlModal
}
from
'
@gitlab/ui
'
;
import
MarkdownField
from
'
~/vue_shared/components/markdown/field.vue
'
;
import
MarkdownField
from
'
~/vue_shared/components/markdown/field.vue
'
;
import
{
s__
}
from
'
~/locale
'
;
export
default
{
export
default
{
name
:
'
DesignReplyForm
'
,
name
:
'
DesignReplyForm
'
,
...
@@ -23,11 +24,42 @@ export default {
...
@@ -23,11 +24,42 @@ export default {
type
:
Boolean
,
type
:
Boolean
,
required
:
true
,
required
:
true
,
},
},
isNewComment
:
{
type
:
Boolean
,
required
:
false
,
default
:
true
,
},
},
data
()
{
return
{
formText
:
this
.
value
,
};
},
},
computed
:
{
computed
:
{
hasValue
()
{
hasValue
()
{
return
this
.
value
.
trim
().
length
>
0
;
return
this
.
value
.
trim
().
length
>
0
;
},
},
modalSettings
()
{
if
(
this
.
isNewComment
)
{
return
{
title
:
s__
(
'
DesignManagement|Cancel comment confirmation
'
),
okTitle
:
s__
(
'
DesignManagement|Discard comment
'
),
cancelTitle
:
s__
(
'
DesignManagement|Keep comment
'
),
content
:
s__
(
'
DesignManagement|Are you sure you want to cancel creating this comment?
'
),
};
}
return
{
title
:
s__
(
'
DesignManagement|Cancel comment update confirmation
'
),
okTitle
:
s__
(
'
DesignManagement|Cancel changes
'
),
cancelTitle
:
s__
(
'
DesignManagement|Keep changes
'
),
content
:
s__
(
'
DesignManagement|Are you sure you want to cancel changes to this comment?
'
),
};
},
buttonText
()
{
return
this
.
isNewComment
?
s__
(
'
DesignManagement|Comment
'
)
:
s__
(
'
DesignManagement|Save comment
'
);
},
},
},
mounted
()
{
mounted
()
{
this
.
$refs
.
textarea
.
focus
();
this
.
$refs
.
textarea
.
focus
();
...
@@ -37,7 +69,7 @@ export default {
...
@@ -37,7 +69,7 @@ export default {
if
(
this
.
hasValue
)
this
.
$emit
(
'
submitForm
'
);
if
(
this
.
hasValue
)
this
.
$emit
(
'
submitForm
'
);
},
},
cancelComment
()
{
cancelComment
()
{
if
(
this
.
hasValue
)
{
if
(
this
.
hasValue
&&
this
.
formText
!==
this
.
value
)
{
this
.
$refs
.
cancelCommentModal
.
show
();
this
.
$refs
.
cancelCommentModal
.
show
();
}
else
{
}
else
{
this
.
$emit
(
'
cancelForm
'
);
this
.
$emit
(
'
cancelForm
'
);
...
@@ -85,7 +117,7 @@ export default {
...
@@ -85,7 +117,7 @@ export default {
data-qa-selector=
"save_comment_button"
data-qa-selector=
"save_comment_button"
@
click=
"$emit('submitForm')"
@
click=
"$emit('submitForm')"
>
>
{{
__('Comment')
}}
{{
buttonText
}}
</gl-deprecated-button>
</gl-deprecated-button>
<gl-deprecated-button
ref=
"cancelButton"
@
click=
"cancelComment"
>
{{
<gl-deprecated-button
ref=
"cancelButton"
@
click=
"cancelComment"
>
{{
__('Cancel')
__('Cancel')
...
@@ -94,12 +126,12 @@ export default {
...
@@ -94,12 +126,12 @@ export default {
<gl-modal
<gl-modal
ref=
"cancelCommentModal"
ref=
"cancelCommentModal"
ok-variant=
"danger"
ok-variant=
"danger"
:title=
"
s__('DesignManagement|Cancel comment confirmation')
"
:title=
"
modalSettings.title
"
:ok-title=
"
s__('DesignManagement|Discard comment')
"
:ok-title=
"
modalSettings.okTitle
"
:cancel-title=
"
s__('DesignManagement|Keep comment')
"
:cancel-title=
"
modalSettings.cancelTitle
"
modal-id=
"cancel-comment-modal"
modal-id=
"cancel-comment-modal"
@
ok=
"$emit('cancelForm')"
@
ok=
"$emit('cancelForm')"
>
{{
s__('DesignManagement|Are you sure you want to cancel creating this comment?')
}}
>
{{
modalSettings.content
}}
</gl-modal>
</gl-modal>
</form>
</form>
</template>
</template>
app/assets/javascripts/design_management/graphql/mutations/update_note.mutation.graphql
0 → 100644
View file @
0496b76b
#import "../fragments/designNote.fragment.graphql"
mutation
updateNote
(
$input
:
UpdateNoteInput
!)
{
updateNote
(
input
:
$input
)
{
note
{
...
DesignNote
}
errors
}
}
app/assets/javascripts/design_management/pages/design/index.vue
View file @
0496b76b
...
@@ -32,6 +32,7 @@ import {
...
@@ -32,6 +32,7 @@ import {
UPDATE_IMAGE_DIFF_NOTE_ERROR
,
UPDATE_IMAGE_DIFF_NOTE_ERROR
,
DESIGN_NOT_FOUND_ERROR
,
DESIGN_NOT_FOUND_ERROR
,
DESIGN_VERSION_NOT_EXIST_ERROR
,
DESIGN_VERSION_NOT_EXIST_ERROR
,
UPDATE_NOTE_ERROR
,
designDeletionError
,
designDeletionError
,
}
from
'
../../utils/error_messages
'
;
}
from
'
../../utils/error_messages
'
;
import
{
DESIGNS_ROUTE_NAME
}
from
'
../../router/constants
'
;
import
{
DESIGNS_ROUTE_NAME
}
from
'
../../router/constants
'
;
...
@@ -231,6 +232,9 @@ export default {
...
@@ -231,6 +232,9 @@ export default {
onCreateImageDiffNoteError
(
e
)
{
onCreateImageDiffNoteError
(
e
)
{
this
.
onError
(
ADD_IMAGE_DIFF_NOTE_ERROR
,
e
);
this
.
onError
(
ADD_IMAGE_DIFF_NOTE_ERROR
,
e
);
},
},
onUpdateNoteError
(
e
)
{
this
.
onError
(
UPDATE_NOTE_ERROR
,
e
);
},
onDesignDiscussionError
(
e
)
{
onDesignDiscussionError
(
e
)
{
this
.
onError
(
ADD_DISCUSSION_COMMENT_ERROR
,
e
);
this
.
onError
(
ADD_DISCUSSION_COMMENT_ERROR
,
e
);
},
},
...
@@ -329,6 +333,7 @@ export default {
...
@@ -329,6 +333,7 @@ export default {
:discussion-index=
"index + 1"
:discussion-index=
"index + 1"
:markdown-preview-path=
"markdownPreviewPath"
:markdown-preview-path=
"markdownPreviewPath"
@
error=
"onDesignDiscussionError"
@
error=
"onDesignDiscussionError"
@
updateNoteError=
"onUpdateNoteError"
/>
/>
<apollo-mutation
<apollo-mutation
v-if=
"annotationCoordinates"
v-if=
"annotationCoordinates"
...
@@ -345,7 +350,7 @@ export default {
...
@@ -345,7 +350,7 @@ export default {
v-model=
"comment"
v-model=
"comment"
:is-saving=
"loading"
:is-saving=
"loading"
:markdown-preview-path=
"markdownPreviewPath"
:markdown-preview-path=
"markdownPreviewPath"
@
submitForm=
"mutate
()
"
@
submitForm=
"mutate"
@
cancelForm=
"closeCommentForm"
@
cancelForm=
"closeCommentForm"
/>
/>
</apollo-mutation>
</apollo-mutation>
...
...
app/assets/javascripts/design_management/utils/cache_update.js
View file @
0496b76b
...
@@ -214,7 +214,7 @@ const onError = (data, message) => {
...
@@ -214,7 +214,7 @@ const onError = (data, message) => {
throw
new
Error
(
data
.
errors
);
throw
new
Error
(
data
.
errors
);
};
};
const
hasErrors
=
({
errors
=
[]
})
=>
errors
?.
length
;
export
const
hasErrors
=
({
errors
=
[]
})
=>
errors
?.
length
;
/**
/**
* Updates a store after design deletion
* Updates a store after design deletion
...
...
app/assets/javascripts/design_management/utils/error_messages.js
View file @
0496b76b
...
@@ -12,6 +12,8 @@ export const UPDATE_IMAGE_DIFF_NOTE_ERROR = s__(
...
@@ -12,6 +12,8 @@ export const UPDATE_IMAGE_DIFF_NOTE_ERROR = s__(
'
DesignManagement|Could not update discussion. Please try again.
'
,
'
DesignManagement|Could not update discussion. Please try again.
'
,
);
);
export
const
UPDATE_NOTE_ERROR
=
s__
(
'
DesignManagement|Could not update note. Please try again.
'
);
export
const
UPLOAD_DESIGN_ERROR
=
s__
(
export
const
UPLOAD_DESIGN_ERROR
=
s__
(
'
DesignManagement|Error uploading a new design. Please try again.
'
,
'
DesignManagement|Error uploading a new design. Please try again.
'
,
);
);
...
...
changelogs/unreleased/118609-design-comment-edit-comment-text.yml
0 → 100644
View file @
0496b76b
---
title
:
'
Resolve
Design
Comment:
Edit
Comment
text'
merge_request
:
30479
author
:
type
:
added
locale/gitlab.pot
View file @
0496b76b
...
@@ -7220,15 +7220,27 @@ msgstr ""
...
@@ -7220,15 +7220,27 @@ msgstr ""
msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
msgid "DesignManagement|Adding a design with the same filename replaces the file in a new version."
msgstr ""
msgstr ""
msgid "DesignManagement|Are you sure you want to cancel changes to this comment?"
msgstr ""
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
msgid "DesignManagement|Are you sure you want to cancel creating this comment?"
msgstr ""
msgstr ""
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgid "DesignManagement|Are you sure you want to delete the selected designs?"
msgstr ""
msgstr ""
msgid "DesignManagement|Cancel changes"
msgstr ""
msgid "DesignManagement|Cancel comment confirmation"
msgid "DesignManagement|Cancel comment confirmation"
msgstr ""
msgstr ""
msgid "DesignManagement|Cancel comment update confirmation"
msgstr ""
msgid "DesignManagement|Comment"
msgstr ""
msgid "DesignManagement|Could not add a new comment. Please try again."
msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr ""
msgstr ""
...
@@ -7238,6 +7250,9 @@ msgstr ""
...
@@ -7238,6 +7250,9 @@ msgstr ""
msgid "DesignManagement|Could not update discussion. Please try again."
msgid "DesignManagement|Could not update discussion. Please try again."
msgstr ""
msgstr ""
msgid "DesignManagement|Could not update note. Please try again."
msgstr ""
msgid "DesignManagement|Delete"
msgid "DesignManagement|Delete"
msgstr ""
msgstr ""
...
@@ -7265,12 +7280,18 @@ msgstr ""
...
@@ -7265,12 +7280,18 @@ msgstr ""
msgid "DesignManagement|Go to previous design"
msgid "DesignManagement|Go to previous design"
msgstr ""
msgstr ""
msgid "DesignManagement|Keep changes"
msgstr ""
msgid "DesignManagement|Keep comment"
msgid "DesignManagement|Keep comment"
msgstr ""
msgstr ""
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr ""
msgstr ""
msgid "DesignManagement|Save comment"
msgstr ""
msgid "DesignManagement|Select all"
msgid "DesignManagement|Select all"
msgstr ""
msgstr ""
...
...
spec/frontend/design_management/components/design_notes/__snapshots__/design_note_spec.js.snap
View file @
0496b76b
...
@@ -3,7 +3,7 @@
...
@@ -3,7 +3,7 @@
exports[`Design note component should match the snapshot 1`] = `
exports[`Design note component should match the snapshot 1`] = `
<timeline-entry-item-stub
<timeline-entry-item-stub
class="design-note note-form"
class="design-note note-form"
id="note_
undefined
"
id="note_
123
"
>
>
<user-avatar-link-stub
<user-avatar-link-stub
imgalt=""
imgalt=""
...
@@ -16,50 +16,55 @@ exports[`Design note component should match the snapshot 1`] = `
...
@@ -16,50 +16,55 @@ exports[`Design note component should match the snapshot 1`] = `
username=""
username=""
/>
/>
<a
<div
class="js-user-link"
class="d-flex justify-content-between"
data-user-id="author-id"
>
<span
class="note-header-author-name bold"
>
</span>
<!---->
<span
class="note-headline-light"
>
@
</span>
</a>
<span
class="note-headline-light note-headline-meta"
>
>
<span
<div>
class="system-note-message"
<a
/>
class="js-user-link"
data-user-id="author-id"
<span
>
class="system-note-separator"
<span
/>
class="note-header-author-name bold"
>
</span>
<!---->
<span
class="note-headline-light"
>
@
</span>
</a>
<span
class="note-headline-light note-headline-meta"
>
<span
class="system-note-message"
/>
<!---->
</span>
</div>
<a
<button
class="note-timestamp system-note-separator"
class="note-action-button js-note-edit btn btn-transparent qa-note-edit-button"
href="#note_undefined"
title="Edit comment"
type="button"
>
>
<
time-ago-tooltip
-stub
<
gl-icon
-stub
c
ssclass="
"
c
lass="link-highlight
"
time="2019-07-26T15:02:20Z
"
name="pencil
"
tooltipplacement="bottom
"
size="16
"
/>
/>
</
a
>
</
button
>
</
span
>
</
div
>
<div
<div
class="note-text md"
class="note-text
js-note-text
md"
data-qa-selector="note_content"
data-qa-selector="note_content"
/>
/>
</timeline-entry-item-stub>
</timeline-entry-item-stub>
...
...
spec/frontend/design_management/components/design_notes/__snapshots__/design_reply_form_spec.js.snap
0 → 100644
View file @
0496b76b
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Design reply form component renders button text as "Comment" when creating a comment 1`] = `
"<button data-track-event=\\"click_button\\" data-qa-selector=\\"save_comment_button\\" type=\\"submit\\" disabled=\\"disabled\\" class=\\"btn btn-success btn-md disabled\\">
<!---->
Comment
</button>"
`;
exports[`Design reply form component renders button text as "Save comment" when creating a comment 1`] = `
"<button data-track-event=\\"click_button\\" data-qa-selector=\\"save_comment_button\\" type=\\"submit\\" disabled=\\"disabled\\" class=\\"btn btn-success btn-md disabled\\">
<!---->
Save comment
</button>"
`;
spec/frontend/design_management/components/design_notes/design_note_spec.js
View file @
0496b76b
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
ApolloMutation
}
from
'
vue-apollo
'
;
import
DesignNote
from
'
~/design_management/components/design_notes/design_note.vue
'
;
import
DesignNote
from
'
~/design_management/components/design_notes/design_note.vue
'
;
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
TimeAgoTooltip
from
'
~/vue_shared/components/time_ago_tooltip.vue
'
;
import
TimeAgoTooltip
from
'
~/vue_shared/components/time_ago_tooltip.vue
'
;
import
DesignReplyForm
from
'
~/design_management/components/design_notes/design_reply_form.vue
'
;
const
scrollIntoViewMock
=
jest
.
fn
();
const
scrollIntoViewMock
=
jest
.
fn
();
const
note
=
{
id
:
'
gid://gitlab/DiffNote/123
'
,
author
:
{
id
:
'
author-id
'
,
},
body
:
'
test
'
,
};
HTMLElement
.
prototype
.
scrollIntoView
=
scrollIntoViewMock
;
HTMLElement
.
prototype
.
scrollIntoView
=
scrollIntoViewMock
;
const
$route
=
{
const
$route
=
{
hash
:
'
#note_123
'
,
hash
:
'
#note_123
'
,
};
};
const
mutate
=
jest
.
fn
().
mockResolvedValue
({
data
:
{
updateNote
:
{}
}
});
describe
(
'
Design note component
'
,
()
=>
{
describe
(
'
Design note component
'
,
()
=>
{
let
wrapper
;
let
wrapper
;
const
findUserAvatar
=
()
=>
wrapper
.
find
(
UserAvatarLink
);
const
findUserAvatar
=
()
=>
wrapper
.
find
(
UserAvatarLink
);
const
findUserLink
=
()
=>
wrapper
.
find
(
'
.js-user-link
'
);
const
findUserLink
=
()
=>
wrapper
.
find
(
'
.js-user-link
'
);
const
findReplyForm
=
()
=>
wrapper
.
find
(
DesignReplyForm
);
const
findEditButton
=
()
=>
wrapper
.
find
(
'
.js-note-edit
'
);
const
findNoteContent
=
()
=>
wrapper
.
find
(
'
.js-note-text
'
);
function
createComponent
(
props
=
{})
{
function
createComponent
(
props
=
{}
,
data
=
{
isEditing
:
false
}
)
{
wrapper
=
shallowMount
(
DesignNote
,
{
wrapper
=
shallowMount
(
DesignNote
,
{
propsData
:
{
propsData
:
{
note
:
{},
note
:
{},
...
props
,
...
props
,
},
},
data
()
{
return
{
...
data
,
};
},
mocks
:
{
mocks
:
{
$route
,
$route
,
$apollo
:
{
mutate
,
},
},
stubs
:
{
ApolloMutation
,
},
},
});
});
}
}
...
@@ -34,13 +59,7 @@ describe('Design note component', () => {
...
@@ -34,13 +59,7 @@ describe('Design note component', () => {
it
(
'
should match the snapshot
'
,
()
=>
{
it
(
'
should match the snapshot
'
,
()
=>
{
createComponent
({
createComponent
({
note
:
{
note
,
id
:
'
1
'
,
createdAt
:
'
2019-07-26T15:02:20Z
'
,
author
:
{
id
:
'
author-id
'
,
},
},
});
});
expect
(
wrapper
.
element
).
toMatchSnapshot
();
expect
(
wrapper
.
element
).
toMatchSnapshot
();
...
@@ -48,12 +67,7 @@ describe('Design note component', () => {
...
@@ -48,12 +67,7 @@ describe('Design note component', () => {
it
(
'
should render an author
'
,
()
=>
{
it
(
'
should render an author
'
,
()
=>
{
createComponent
({
createComponent
({
note
:
{
note
,
id
:
'
1
'
,
author
:
{
id
:
'
author-id
'
,
},
},
});
});
expect
(
findUserAvatar
().
exists
()).
toBe
(
true
);
expect
(
findUserAvatar
().
exists
()).
toBe
(
true
);
...
@@ -63,11 +77,8 @@ describe('Design note component', () => {
...
@@ -63,11 +77,8 @@ describe('Design note component', () => {
it
(
'
should render a time ago tooltip if note has createdAt property
'
,
()
=>
{
it
(
'
should render a time ago tooltip if note has createdAt property
'
,
()
=>
{
createComponent
({
createComponent
({
note
:
{
note
:
{
id
:
'
1
'
,
...
note
,
createdAt
:
'
2019-07-26T15:02:20Z
'
,
createdAt
:
'
2019-07-26T15:02:20Z
'
,
author
:
{
id
:
'
author-id
'
,
},
},
},
});
});
...
@@ -76,14 +87,61 @@ describe('Design note component', () => {
...
@@ -76,14 +87,61 @@ describe('Design note component', () => {
it
(
'
should trigger a scrollIntoView method
'
,
()
=>
{
it
(
'
should trigger a scrollIntoView method
'
,
()
=>
{
createComponent
({
createComponent
({
note
:
{
note
,
id
:
'
gid://gitlab/DiffNote/123
'
,
author
:
{
id
:
'
author-id
'
,
},
},
});
});
expect
(
scrollIntoViewMock
).
toHaveBeenCalled
();
expect
(
scrollIntoViewMock
).
toHaveBeenCalled
();
});
});
it
(
'
should open an edit form on edit button click
'
,
()
=>
{
createComponent
({
note
,
});
findEditButton
().
trigger
(
'
click
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
expect
(
findReplyForm
().
exists
()).
toBe
(
true
);
expect
(
findNoteContent
().
exists
()).
toBe
(
false
);
});
});
describe
(
'
when edit form is rendered
'
,
()
=>
{
beforeEach
(()
=>
{
createComponent
(
{
note
,
},
{
isEditing
:
true
},
);
});
it
(
'
should not render note content and should render reply form
'
,
()
=>
{
expect
(
findNoteContent
().
exists
()).
toBe
(
false
);
expect
(
findReplyForm
().
exists
()).
toBe
(
true
);
});
it
(
'
hides the form on hideForm event
'
,
()
=>
{
findReplyForm
().
vm
.
$emit
(
'
cancelForm
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
expect
(
findReplyForm
().
exists
()).
toBe
(
false
);
expect
(
findNoteContent
().
exists
()).
toBe
(
true
);
});
});
it
(
'
calls a mutation on submitForm event and hides a form
'
,
()
=>
{
findReplyForm
().
vm
.
$emit
(
'
submitForm
'
);
expect
(
mutate
).
toHaveBeenCalled
();
return
mutate
()
.
then
(()
=>
{
return
wrapper
.
vm
.
$nextTick
();
})
.
then
(()
=>
{
expect
(
findReplyForm
().
exists
()).
toBe
(
false
);
expect
(
findNoteContent
().
exists
()).
toBe
(
true
);
});
});
});
});
});
spec/frontend/design_management/components/design_notes/design_reply_form_spec.js
View file @
0496b76b
import
{
mount
}
from
'
@vue/test-utils
'
;
import
{
mount
}
from
'
@vue/test-utils
'
;
import
DesignReplyForm
from
'
~/design_management/components/design_notes/design_reply_form.vue
'
;
import
DesignReplyForm
from
'
~/design_management/components/design_notes/design_reply_form.vue
'
;
const
showModal
=
jest
.
fn
();
const
GlModal
=
{
template
:
'
<div><slot name="modal-title"></slot><slot></slot><slot name="modal-ok"></slot></div>
'
,
methods
:
{
show
:
showModal
,
},
};
describe
(
'
Design reply form component
'
,
()
=>
{
describe
(
'
Design reply form component
'
,
()
=>
{
let
wrapper
;
let
wrapper
;
...
@@ -16,6 +25,7 @@ describe('Design reply form component', () => {
...
@@ -16,6 +25,7 @@ describe('Design reply form component', () => {
isSaving
:
false
,
isSaving
:
false
,
...
props
,
...
props
,
},
},
stubs
:
{
GlModal
},
});
});
}
}
...
@@ -29,6 +39,18 @@ describe('Design reply form component', () => {
...
@@ -29,6 +39,18 @@ describe('Design reply form component', () => {
expect
(
findTextarea
().
element
).
toEqual
(
document
.
activeElement
);
expect
(
findTextarea
().
element
).
toEqual
(
document
.
activeElement
);
});
});
it
(
'
renders button text as "Comment" when creating a comment
'
,
()
=>
{
createComponent
();
expect
(
findSubmitButton
().
html
()).
toMatchSnapshot
();
});
it
(
'
renders button text as "Save comment" when creating a comment
'
,
()
=>
{
createComponent
({
isNewComment
:
false
});
expect
(
findSubmitButton
().
html
()).
toMatchSnapshot
();
});
describe
(
'
when form has no text
'
,
()
=>
{
describe
(
'
when form has no text
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(()
=>
{
createComponent
({
createComponent
({
...
@@ -120,16 +142,34 @@ describe('Design reply form component', () => {
...
@@ -120,16 +142,34 @@ describe('Design reply form component', () => {
});
});
});
});
it
(
'
opens confirmation modal on pressing Escape button
'
,
()
=>
{
it
(
'
emits cancelForm event on Escape key if text was not changed
'
,
()
=>
{
findTextarea
().
trigger
(
'
keyup.esc
'
);
findTextarea
().
trigger
(
'
keyup.esc
'
);
expect
(
findModal
().
exists
()).
toBe
(
true
);
expect
(
wrapper
.
emitted
(
'
cancelForm
'
)).
toBeTruthy
(
);
});
});
it
(
'
opens confirmation modal on
Cancel button click
'
,
()
=>
{
it
(
'
opens confirmation modal on
Escape key when text has changed
'
,
()
=>
{
findCancelButton
().
vm
.
$emit
(
'
click
'
);
wrapper
.
setProps
({
value
:
'
test2
'
}
);
expect
(
findModal
().
exists
()).
toBe
(
true
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
findTextarea
().
trigger
(
'
keyup.esc
'
);
expect
(
showModal
).
toHaveBeenCalled
();
});
});
it
(
'
emits cancelForm event on Cancel button click if text was not changed
'
,
()
=>
{
findCancelButton
().
trigger
(
'
click
'
);
expect
(
wrapper
.
emitted
(
'
cancelForm
'
)).
toBeTruthy
();
});
it
(
'
opens confirmation modal on Cancel button click when text has changed
'
,
()
=>
{
wrapper
.
setProps
({
value
:
'
test2
'
});
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
findCancelButton
().
trigger
(
'
click
'
);
expect
(
showModal
).
toHaveBeenCalled
();
});
});
});
it
(
'
emits cancelForm event on modal Ok button click
'
,
()
=>
{
it
(
'
emits cancelForm event on modal Ok button click
'
,
()
=>
{
...
...
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