Commit 455a60db authored by Tom Quirk's avatar Tom Quirk Committed by Natalia Tepluhina

Refactor addDiscussionComment for immutability

- As per best practice, prefer immutability over destructive updates
when writing updates to Apollo store
-  Additionally, use computed value for mutation payload
parent c7e7a041
...@@ -56,7 +56,7 @@ export default { ...@@ -56,7 +56,7 @@ export default {
</script> </script>
<template> <template>
<ApolloMutation <apollo-mutation
v-slot="{ mutate, loading, error }" v-slot="{ mutate, loading, error }"
:mutation="$options.destroyDesignMutation" :mutation="$options.destroyDesignMutation"
:variables="{ :variables="{
...@@ -69,5 +69,5 @@ export default { ...@@ -69,5 +69,5 @@ export default {
v-on="$listeners" v-on="$listeners"
> >
<slot v-bind="{ mutate, loading, error }"></slot> <slot v-bind="{ mutate, loading, error }"></slot>
</ApolloMutation> </apollo-mutation>
</template> </template>
<script> <script>
import { ApolloMutation } from 'vue-apollo';
import { s__ } from '~/locale'; import { s__ } from '~/locale';
import createFlash from '~/flash'; import createFlash from '~/flash';
import ReplyPlaceholder from '~/notes/components/discussion_reply_placeholder.vue'; import ReplyPlaceholder from '~/notes/components/discussion_reply_placeholder.vue';
...@@ -11,6 +12,7 @@ import { extractCurrentDiscussion } from '../../utils/design_management_utils'; ...@@ -11,6 +12,7 @@ import { extractCurrentDiscussion } from '../../utils/design_management_utils';
export default { export default {
components: { components: {
ApolloMutation,
DesignNote, DesignNote,
ReplyPlaceholder, ReplyPlaceholder,
DesignReplyForm, DesignReplyForm,
...@@ -43,28 +45,24 @@ export default { ...@@ -43,28 +45,24 @@ export default {
return { return {
discussionComment: '', discussionComment: '',
isFormRendered: false, isFormRendered: false,
isNoteSaving: false,
}; };
}, },
computed: { computed: {
isSubmitButtonDisabled() { mutationPayload() {
return this.discussionComment.trim().length === 0; return {
},
},
methods: {
addDiscussionComment() {
this.isNoteSaving = true;
return this.$apollo
.mutate({
mutation: createNoteMutation,
variables: {
input: {
noteableId: this.noteableId, noteableId: this.noteableId,
body: this.discussionComment, body: this.discussionComment,
discussionId: this.discussion.id, discussionId: this.discussion.id,
};
},
}, },
methods: {
addDiscussionComment(
store,
{
data: { createNote },
}, },
update: (store, { data: { createNote } }) => { ) {
const data = store.readQuery({ const data = store.readQuery({
query: getDesignQuery, query: getDesignQuery,
variables: { variables: {
...@@ -76,25 +74,32 @@ export default { ...@@ -76,25 +74,32 @@ export default {
data.design.discussions, data.design.discussions,
this.discussion.id, this.discussion.id,
); );
currentDiscussion.node.notes.edges.push({ currentDiscussion.node.notes.edges = [
...currentDiscussion.node.notes.edges,
{
__typename: 'NoteEdge', __typename: 'NoteEdge',
node: createNote.note, node: createNote.note,
},
];
store.writeQuery({
query: getDesignQuery,
data: {
...data,
design: {
...data.design,
notesCount: data.design.notesCount + 1,
},
},
}); });
data.design.notesCount += 1;
store.writeQuery({ query: getDesignQuery, data });
}, },
}) onDone() {
.then(() => {
this.discussionComment = ''; this.discussionComment = '';
this.hideForm(); this.hideForm();
}) },
.catch(e => { onError(e) {
createFlash(s__('DesignManagement|Could not add a new comment. Please try again')); createFlash(s__('DesignManagement|Could not add a new comment. Please try again'));
throw e; throw e;
})
.finally(() => {
this.isNoteSaving = false;
});
}, },
hideForm() { hideForm() {
this.isFormRendered = false; this.isFormRendered = false;
...@@ -103,6 +108,7 @@ export default { ...@@ -103,6 +108,7 @@ export default {
this.isFormRendered = true; this.isFormRendered = true;
}, },
}, },
createNoteMutation,
}; };
</script> </script>
...@@ -121,14 +127,25 @@ export default { ...@@ -121,14 +127,25 @@ export default {
:button-text="__('Reply...')" :button-text="__('Reply...')"
@onClick="showForm" @onClick="showForm"
/> />
<design-reply-form <apollo-mutation
v-else v-else
v-slot="{ mutate, loading, error }"
:mutation="$options.createNoteMutation"
:variables="{
input: mutationPayload,
}"
:update="addDiscussionComment"
@done="onDone"
@error="onError"
>
<design-reply-form
v-model="discussionComment" v-model="discussionComment"
:is-saving="isNoteSaving" :is-saving="loading"
:markdown-preview-path="markdownPreviewPath" :markdown-preview-path="markdownPreviewPath"
@submitForm="addDiscussionComment" @submitForm="mutate"
@cancelForm="hideForm" @cancelForm="hideForm"
/> />
</apollo-mutation>
</div> </div>
</div> </div>
</div> </div>
......
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { ApolloMutation } from 'vue-apollo';
import ReplyPlaceholder from '~/notes/components/discussion_reply_placeholder.vue'; import ReplyPlaceholder from '~/notes/components/discussion_reply_placeholder.vue';
import DesignDiscussion from 'ee/design_management/components/design_notes/design_discussion.vue'; import DesignDiscussion from 'ee/design_management/components/design_notes/design_discussion.vue';
import DesignNote from 'ee/design_management/components/design_notes/design_note.vue'; import DesignNote from 'ee/design_management/components/design_notes/design_note.vue';
...@@ -49,6 +50,7 @@ describe('Design discussions component', () => { ...@@ -49,6 +50,7 @@ describe('Design discussions component', () => {
}, },
stubs: { stubs: {
ReplyPlaceholder, ReplyPlaceholder,
ApolloMutation,
}, },
mocks: { $apollo }, mocks: { $apollo },
}); });
...@@ -92,7 +94,7 @@ describe('Design discussions component', () => { ...@@ -92,7 +94,7 @@ describe('Design discussions component', () => {
expect(mutate).toHaveBeenCalledWith(mutationVariables); expect(mutate).toHaveBeenCalledWith(mutationVariables);
return wrapper.vm.addDiscussionComment(); return mutate({ variables: mutationVariables });
}) })
.then(() => { .then(() => {
expect(findReplyForm().exists()).toBe(false); expect(findReplyForm().exists()).toBe(false);
......
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