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,58 +45,61 @@ export default { ...@@ -43,58 +45,61 @@ export default {
return { return {
discussionComment: '', discussionComment: '',
isFormRendered: false, isFormRendered: false,
isNoteSaving: false,
}; };
}, },
computed: { computed: {
isSubmitButtonDisabled() { mutationPayload() {
return this.discussionComment.trim().length === 0; return {
noteableId: this.noteableId,
body: this.discussionComment,
discussionId: this.discussion.id,
};
}, },
}, },
methods: { methods: {
addDiscussionComment() { addDiscussionComment(
this.isNoteSaving = true; store,
return this.$apollo {
.mutate({ data: { createNote },
mutation: createNoteMutation, },
variables: { ) {
input: { const data = store.readQuery({
noteableId: this.noteableId, query: getDesignQuery,
body: this.discussionComment, variables: {
discussionId: this.discussion.id, id: this.designId,
}, version: this.designsVersion,
}, },
update: (store, { data: { createNote } }) => { });
const data = store.readQuery({ const currentDiscussion = extractCurrentDiscussion(
query: getDesignQuery, data.design.discussions,
variables: { this.discussion.id,
id: this.designId, );
version: this.designsVersion, currentDiscussion.node.notes.edges = [
}, ...currentDiscussion.node.notes.edges,
}); {
const currentDiscussion = extractCurrentDiscussion( __typename: 'NoteEdge',
data.design.discussions, node: createNote.note,
this.discussion.id, },
); ];
currentDiscussion.node.notes.edges.push({
__typename: 'NoteEdge', store.writeQuery({
node: createNote.note, query: getDesignQuery,
}); data: {
data.design.notesCount += 1; ...data,
store.writeQuery({ query: getDesignQuery, data }); design: {
...data.design,
notesCount: data.design.notesCount + 1,
}, },
}) },
.then(() => { });
this.discussionComment = ''; },
this.hideForm(); onDone() {
}) this.discussionComment = '';
.catch(e => { this.hideForm();
createFlash(s__('DesignManagement|Could not add a new comment. Please try again')); },
throw e; onError(e) {
}) createFlash(s__('DesignManagement|Could not add a new comment. Please try again'));
.finally(() => { throw e;
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-model="discussionComment" v-slot="{ mutate, loading, error }"
:is-saving="isNoteSaving" :mutation="$options.createNoteMutation"
:markdown-preview-path="markdownPreviewPath" :variables="{
@submitForm="addDiscussionComment" input: mutationPayload,
@cancelForm="hideForm" }"
/> :update="addDiscussionComment"
@done="onDone"
@error="onError"
>
<design-reply-form
v-model="discussionComment"
:is-saving="loading"
:markdown-preview-path="markdownPreviewPath"
@submitForm="mutate"
@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