Commit 7c99ca9a authored by Natalia Tepluhina's avatar Natalia Tepluhina

Merge branch '35074-move-updating-apollo-cache-logic-to-utils' into 'master'

Abstract Apollo Cache update logic

Closes #35074

See merge request gitlab-org/gitlab!20026
parents 4823951e a97561af
<script>
import { __, s__, sprintf } from '~/locale';
import createFlash from '~/flash';
import { ApolloMutation } from 'vue-apollo';
import projectQuery from '../graphql/queries/project.query.graphql';
import destroyDesignMutation from '../graphql/mutations/destroyDesign.mutation.graphql';
import { updateStoreAfterDesignsDelete } from '../utils/design_management_utils';
import { updateStoreAfterDesignsDelete } from '../utils/cache_update';
import { designDeletionError } from '../utils/error_messages';
export default {
components: {
......@@ -34,12 +34,8 @@ export default {
},
methods: {
onError() {
const design = this.filenames.length > 1 ? __('designs') : __('a design');
createFlash(
sprintf(s__('DesignManagement|We could not delete %{design}. Please try again.'), {
design,
}),
);
const errorMessage = designDeletionError(this.filenames.length === 1);
createFlash(errorMessage);
},
updateStoreAfterDelete(
store,
......
<script>
import { ApolloMutation } from 'vue-apollo';
import { s__ } from '~/locale';
import createFlash from '~/flash';
import ReplyPlaceholder from '~/notes/components/discussion_reply_placeholder.vue';
import allVersionsMixin from '../../mixins/all_versions';
......@@ -8,7 +7,8 @@ import createNoteMutation from '../../graphql/mutations/createNote.mutation.grap
import getDesignQuery from '../../graphql/queries/getDesign.query.graphql';
import DesignNote from './design_note.vue';
import DesignReplyForm from './design_reply_form.vue';
import { extractCurrentDiscussion, extractDesign } from '../../utils/design_management_utils';
import { updateStoreAfterAddDiscussionComment } from '../../utils/cache_update';
import { ADD_DISCUSSION_COMMENT_ERROR } from '../../utils/error_messages';
export default {
components: {
......@@ -71,40 +71,14 @@ export default {
data: { createNote },
},
) {
const data = store.readQuery({
query: getDesignQuery,
variables: this.designVariables,
});
const design = extractDesign(data);
const currentDiscussion = extractCurrentDiscussion(design.discussions, this.discussion.id);
currentDiscussion.node.notes.edges = [
...currentDiscussion.node.notes.edges,
{
__typename: 'NoteEdge',
node: createNote.note,
},
];
design.notesCount += 1;
store.writeQuery({
query: getDesignQuery,
variables: this.designVariables,
data: {
...data,
design: {
...design,
},
},
});
updateStoreAfterAddDiscussionComment(store, createNote, getDesignQuery, this.designVariables);
},
onDone() {
this.discussionComment = '';
this.hideForm();
},
onError(e) {
createFlash(s__('DesignManagement|Could not add a new comment. Please try again'));
throw e;
onError() {
createFlash(ADD_DISCUSSION_COMMENT_ERROR);
},
hideForm() {
this.isFormRendered = false;
......
......@@ -14,6 +14,7 @@ import getDesignQuery from '../../graphql/queries/getDesign.query.graphql';
import appDataQuery from '../../graphql/queries/appData.query.graphql';
import createImageDiffNoteMutation from '../../graphql/mutations/createImageDiffNote.mutation.graphql';
import { extractDiscussions, extractDesign } from '../../utils/design_management_utils';
import { ADD_DISCUSSION_COMMENT_ERROR } from '../../utils/error_messages';
export default {
components: {
......@@ -175,12 +176,13 @@ export default {
})
.then(() => {
this.closeCommentForm();
this.isNoteSaving = false;
})
.catch(e => {
createFlash(ADD_DISCUSSION_COMMENT_ERROR);
throw new Error(e);
})
.finally(() => {
this.isNoteSaving = false;
createFlash(s__('DesignManagement|Could not create new discussion, please try again.'));
throw e;
});
},
openCommentForm(position) {
......
......@@ -12,6 +12,8 @@ import uploadDesignMutation from '../graphql/mutations/uploadDesign.mutation.gra
import permissionsQuery from '../graphql/queries/permissions.query.graphql';
import projectQuery from '../graphql/queries/project.query.graphql';
import allDesignsMixin from '../mixins/all_designs';
import { UPLOAD_DESIGN_ERROR } from '../utils/error_messages';
import { updateStoreAfterUploadDesign } from '../utils/cache_update';
const MAXIMUM_FILE_UPLOAD_LIMIT = 10;
......@@ -145,56 +147,7 @@ export default {
hasUpload: true,
},
update: (store, { data: { designManagementUpload } }) => {
const data = store.readQuery(this.projectQueryBody);
const newDesigns = data.project.issue.designCollection.designs.edges.reduce(
(acc, design) => {
if (!acc.find(d => d.filename === design.node.filename)) {
acc.push(design.node);
}
return acc;
},
designManagementUpload.designs,
);
let newVersionNode;
const findNewVersions = designManagementUpload.designs.find(design => design.versions);
if (findNewVersions) {
const findNewVersionsEdges = findNewVersions.versions.edges;
if (findNewVersionsEdges && findNewVersionsEdges.length) {
newVersionNode = [findNewVersionsEdges[0]];
}
}
const newVersions = [
...(newVersionNode || []),
...data.project.issue.designCollection.versions.edges,
];
const updatedDesigns = {
__typename: 'DesignCollection',
designs: {
__typename: 'DesignConnection',
edges: newDesigns.map(design => ({
__typename: 'DesignEdge',
node: design,
})),
},
versions: {
__typename: 'DesignVersionConnection',
edges: newVersions,
},
};
data.project.issue.designCollection = updatedDesigns;
store.writeQuery({
...this.projectQueryBody,
data,
});
updateStoreAfterUploadDesign(store, designManagementUpload, this.projectQueryBody);
},
optimisticResponse: {
// False positive i18n lint: https://gitlab.com/gitlab-org/frontend/eslint-plugin-i18n/issues/26
......@@ -210,7 +163,7 @@ export default {
this.$router.push({ name: 'designs' });
})
.catch(e => {
createFlash(s__('DesignManagement|Error uploading a new design. Please try again'));
createFlash(UPLOAD_DESIGN_ERROR);
throw e;
})
.finally(() => {
......
import createFlash from '~/flash';
import { extractCurrentDiscussion, extractDesign } from './design_management_utils';
import {
ADD_IMAGE_DIFF_NOTE_ERROR,
ADD_DISCUSSION_COMMENT_ERROR,
UPLOAD_DESIGN_ERROR,
designDeletionError,
} from './error_messages';
const deleteDesignsFromStore = (store, query, selectedDesigns) => {
const data = store.readQuery(query);
const changedDesigns = data.project.issue.designCollection.designs.edges.filter(
({ node }) => !selectedDesigns.includes(node.filename),
);
data.project.issue.designCollection.designs.edges = [...changedDesigns];
store.writeQuery({
...query,
data,
});
};
/**
* Adds a new version of designs to store
*
* @param {Object} store
* @param {Object} query
* @param {Object} version
*/
const addNewVersionToStore = (store, query, version) => {
if (!version) return;
const data = store.readQuery(query);
const newEdge = { node: version, __typename: 'DesignVersionEdge' };
data.project.issue.designCollection.versions.edges = [
newEdge,
...data.project.issue.designCollection.versions.edges,
];
store.writeQuery({
...query,
data,
});
};
const addDiscussionCommentToStore = (store, createNote, query, queryVariables) => {
const data = store.readQuery({
query,
variables: queryVariables,
});
const design = extractDesign(data);
const currentDiscussion = extractCurrentDiscussion(design.discussions, this.discussion.id);
currentDiscussion.node.notes.edges = [
...currentDiscussion.node.notes.edges,
{
__typename: 'NoteEdge',
node: createNote.note,
},
];
design.notesCount += 1;
store.writeQuery({
query,
variables: queryVariables,
data: {
...data,
design: {
...design,
},
},
});
};
const addImageDiffNoteToStore = (store, createImageDiffNote, query) => {
const data = store.readQuery({
query,
variables: {
id: this.id,
version: this.designsVersion,
},
});
const newDiscussion = {
__typename: 'DiscussionEdge',
node: {
// False positive i18n lint: https://gitlab.com/gitlab-org/frontend/eslint-plugin-i18n/issues/26
// eslint-disable-next-line @gitlab/i18n/no-non-i18n-strings
__typename: 'Discussion',
id: createImageDiffNote.note.discussion.id,
replyId: createImageDiffNote.note.discussion.replyId,
notes: {
__typename: 'NoteConnection',
edges: [
{
__typename: 'NoteEdge',
node: createImageDiffNote.note,
},
],
},
},
};
data.design.discussions.edges.push(newDiscussion);
data.design.notesCount += 1;
store.writeQuery({ query, data });
};
const addNewDesignToStore = (store, designManagementUpload, query) => {
const data = store.readQuery(query);
const newDesigns = data.project.issue.designCollection.designs.edges.reduce((acc, design) => {
if (!acc.find(d => d.filename === design.node.filename)) {
acc.push(design.node);
}
return acc;
}, designManagementUpload.designs);
let newVersionNode;
const findNewVersions = designManagementUpload.designs.find(design => design.versions);
if (findNewVersions) {
const findNewVersionsEdges = findNewVersions.versions.edges;
if (findNewVersionsEdges && findNewVersionsEdges.length) {
newVersionNode = [findNewVersionsEdges[0]];
}
}
const newVersions = [
...(newVersionNode || []),
...data.project.issue.designCollection.versions.edges,
];
const updatedDesigns = {
__typename: 'DesignCollection',
designs: {
__typename: 'DesignConnection',
edges: newDesigns.map(design => ({
__typename: 'DesignEdge',
node: design,
})),
},
versions: {
__typename: 'DesignVersionConnection',
edges: newVersions,
},
};
data.project.issue.designCollection = updatedDesigns;
store.writeQuery({
...query,
data,
});
};
const onError = (data, message) => {
createFlash(message);
throw new Error(data.errors);
};
/**
* Updates a store after design deletion
*
* @param {Object} store
* @param {Object} data
* @param {Object} query
* @param {Array} designs
*/
export const updateStoreAfterDesignsDelete = (store, data, query, designs) => {
if (data.errors) {
onError(data, designDeletionError(designs.length === 1));
} else {
deleteDesignsFromStore(store, query, designs);
addNewVersionToStore(store, query, data.version);
}
};
export const updateStoreAfterAddDiscussionComment = (store, data, query, queryVariables) => {
if (data.errors) {
onError(data, ADD_DISCUSSION_COMMENT_ERROR);
} else {
addDiscussionCommentToStore(store, data, query, queryVariables);
}
};
export const updateStoreAfterAddImageDiffNote = (store, data, query) => {
if (data.errors) {
onError(data, ADD_IMAGE_DIFF_NOTE_ERROR);
} else {
addImageDiffNoteToStore(store, data, query);
}
};
export const updateStoreAfterUploadDesign = (store, data, query) => {
if (data.errors) {
onError(data, UPLOAD_DESIGN_ERROR);
} else {
addNewDesignToStore(store, data, query);
}
};
import { s__ } from '~/locale';
import createFlash from '~/flash';
/**
* Returns formatted array that doesn't contain
* `edges`->`node` nesting
......@@ -33,63 +30,6 @@ export const extractDiscussions = discussions =>
export const extractCurrentDiscussion = (discussions, id) =>
discussions.edges.find(({ node }) => node.id === id);
const deleteDesignsFromStore = (store, query, selectedDesigns) => {
const data = store.readQuery(query);
const changedDesigns = data.project.issue.designCollection.designs.edges.filter(
({ node }) => !selectedDesigns.includes(node.filename),
);
data.project.issue.designCollection.designs.edges = [...changedDesigns];
store.writeQuery({
...query,
data,
});
};
/**
* Adds a new version of designs to store
*
* @param {Object} store
* @param {Object} query
* @param {Object} version
*/
const addNewVersionToStore = (store, query, version) => {
if (!version) return;
const data = store.readQuery(query);
const newEdge = { node: version, __typename: 'DesignVersionEdge' };
data.project.issue.designCollection.versions.edges = [
newEdge,
...data.project.issue.designCollection.versions.edges,
];
store.writeQuery({
...query,
data,
});
};
/**
* Updates a store after design deletion
*
* @param {Object} store
* @param {Object} data
* @param {Object} query
* @param {Array} designs
*/
export const updateStoreAfterDesignsDelete = (store, data, query, designs) => {
if (data.errors) {
createFlash(s__('DesignManagement|We could not delete design(s). Please try again.'));
throw new Error(data.errors);
} else {
deleteDesignsFromStore(store, query, designs);
addNewVersionToStore(store, query, data.version);
}
};
export const findVersionId = id => id.match('::Version/(.+$)')[1];
export const extractDesign = data => data.project.issue.designCollection.designs.edges[0].node;
import { __, s__, sprintf } from '~/locale';
export const designDeletionError = (singular = true) => {
const design = singular ? __('a design') : __('designs');
return sprintf(s__('DesignManagement|We could not delete %{design}. Please try again.'), {
design,
});
};
export const ADD_DISCUSSION_COMMENT_ERROR = s__(
'DesignManagement|Could not add a new comment. Please try again',
);
export const ADD_IMAGE_DIFF_NOTE_ERROR = s__(
'DesignManagement|Could not create new discussion. Please try again.',
);
export const UPLOAD_DESIGN_ERROR = s__(
'DesignManagement|Error uploading a new design. Please try again',
);
......@@ -5770,7 +5770,7 @@ msgstr ""
msgid "DesignManagement|Could not add a new comment. Please try again"
msgstr ""
msgid "DesignManagement|Could not create new discussion, please try again."
msgid "DesignManagement|Could not create new discussion. Please try again."
msgstr ""
msgid "DesignManagement|Could not find design, please try again."
......@@ -5821,9 +5821,6 @@ msgstr ""
msgid "DesignManagement|We could not delete %{design}. Please try again."
msgstr ""
msgid "DesignManagement|We could not delete design(s). Please try again."
msgstr ""
msgid "Designs"
msgstr ""
......
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