Commit cf323691 authored by Phil Hughes's avatar Phil Hughes

Changes GraphQL client to allow for multipart requests

This is to mainly allow for images to be uploaded in design management.
parent 13c26a9b
import ApolloClient from 'apollo-boost';
import { ApolloClient } from 'apollo-client';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { createUploadLink } from 'apollo-upload-client';
import csrf from '~/lib/utils/csrf';
export default (clientState = {}) =>
export default (resolvers = {}) =>
new ApolloClient({
uri: `${gon.relative_url_root}/api/graphql`,
headers: {
[csrf.headerKey]: csrf.token,
},
clientState,
link: createUploadLink({
uri: `${gon.relative_url_root}/api/graphql`,
headers: {
[csrf.headerKey]: csrf.token,
},
}),
cache: new InMemoryCache(),
resolvers,
});
......@@ -46,7 +46,9 @@ Read more about [Vue Apollo][vue-apollo] in the [Vue Apollo documentation][vue-a
### Local state with `apollo-link-state`
It is possible to use our Apollo setup with [apollo-link-state][apollo-link-state] by passing
in the client state object when creating the default client.
in a resolvers object when creating the default client. The default state can be set by writing
to the cache after setting up the default client.
```javascript
import Vue from 'vue';
......@@ -54,15 +56,23 @@ import VueApollo from 'vue-apollo';
import createDefaultClient from '~/lib/graphql';
Vue.use(VueApollo);
const defaultClient = createDefaultClient({
Query: {
...
},
Mutations: {
...
},
});
defaultClient.cache.writeData({
data: {
isLoading: true,
},
});
const apolloProvider = new VueApollo({
defaultClient: createDefaultClient({
defaults: {
testing: true,
},
resolvers: {
...
},
}),
defaultClient,
});
```
......
......@@ -28,31 +28,38 @@ const designsStore = [
];
const defaultClient = createDefaultClient({
defaults: {
designs: designsStore,
},
resolvers: {
Query: {
design(ctx, { id }) {
return designsStore.find(design => design.id === id);
},
Query: {
design(ctx, { id }) {
return designsStore.find(design => design.id === id);
},
Mutation: {
uploadDesign(ctx, { name }, { cache }) {
const designs = name.map(n => ({
...createMockDesign(_.uniqueId()),
name: n,
commentsCount: 0,
}));
},
Mutation: {
uploadDesign(ctx, { files }, { cache }) {
const previousDesigns = cache.readQuery({ query: allDesigns });
const designs = Array.from(files).map(n => ({
...createMockDesign(_.uniqueId()),
name: n.name,
commentsCount: 0,
}));
const data = {
designs: designs.concat(previousDesigns.designs),
};
designsStore.unshift(...designs);
cache.writeData({ data: designs });
cache.writeQuery({ query: allDesigns, data });
return designs;
},
return designs;
},
},
});
defaultClient.cache.writeData({
data: {
designs: designsStore,
},
});
defaultClient
.watchQuery({
query: allDesigns,
......
<script>
import createFlash from '~/flash';
import { s__ } from '~/locale';
import Toolbar from '../../components/toolbar/index.vue';
import DesignImage from '../../components/image.vue';
import getDesignQuery from '../../queries/getDesign.graphql';
......@@ -27,6 +29,12 @@ export default {
id: this.id,
};
},
result({ data }) {
if (!data) {
createFlash(s__('DesignManagement|Could not find design, please try again.'));
this.$router.push('/designs');
}
},
},
},
computed: {
......
......@@ -63,7 +63,7 @@ export default {
onUploadDesign(files) {
if (!this.canCreateDesign) return null;
const optimisticResponse = [...files].map(file => ({
const optimisticResponse = Array.from(files).map(file => ({
__typename: 'Design',
id: -1,
image: '',
......@@ -78,14 +78,15 @@ export default {
.mutate({
mutation: uploadDesignQuery,
variables: {
name: [...files].map(({ name }) => name),
files,
},
update: (store, { data: { uploadDesign } }) => {
const data = store.readQuery({ query: allDesignsQuery });
// update: (store, { data: { uploadDesign } }) => {
// const data = store.readQuery({ query: allDesignsQuery });
// console.log(data, uploadDesign);
data.designs.unshift(...uploadDesign);
store.writeQuery({ query: allDesignsQuery, data });
},
// data.designs.unshift(...uploadDesign);
// store.writeQuery({ query: allDesignsQuery, data });
// },
optimisticResponse: {
__typename: 'Mutation',
uploadDesign: optimisticResponse,
......
mutation addDesigns($name: [String]) {
uploadDesign(name: $name) @client {
mutation addDesigns($files: [Upload!]!) {
uploadDesign(files: $files) @client {
id
image
name
......
......@@ -32,6 +32,15 @@ const router = new VueRouter({
meta: {
el: 'designs',
},
beforeEnter(
{
params: { id },
},
from,
next,
) {
if (id !== -1) next();
},
props: ({ params: { id } }) => ({ id: parseInt(id, 10) }),
},
],
......
......@@ -75,9 +75,8 @@ describe('Design management index page', () => {
.then(() => {
expect(mutate).toHaveBeenCalledWith({
mutation: uploadDesignQuery,
update: expect.any(Function),
variables: {
name: ['test'],
files: [{ name: 'test' }],
},
optimisticResponse: {
__typename: 'Mutation',
......
......@@ -3520,6 +3520,9 @@ msgstr ""
msgid "Description:"
msgstr ""
msgid "DesignManagement|Could not find design, please try again."
msgstr ""
msgid "DesignManagement|Error uploading a new design. Please try again"
msgstr ""
......
......@@ -1114,21 +1114,6 @@ anymatch@^2.0.0:
micromatch "^3.1.4"
normalize-path "^2.1.1"
apollo-boost@^0.3.1:
version "0.3.1"
resolved "https://registry.yarnpkg.com/apollo-boost/-/apollo-boost-0.3.1.tgz#b6a896e020a0eab7e415032fe565734a955c65f8"
integrity sha512-VdXcTMxLBeNvANW/FtiarEkrRr/cepYKG6wTAURdy8CS33WYpEHtIg9S8tAjxwVzIECpE4lWyDKyPLoESJ072Q==
dependencies:
apollo-cache "^1.2.1"
apollo-cache-inmemory "^1.5.1"
apollo-client "^2.5.1"
apollo-link "^1.0.6"
apollo-link-error "^1.0.3"
apollo-link-http "^1.3.1"
graphql-tag "^2.4.2"
ts-invariant "^0.2.1"
tslib "^1.9.3"
apollo-cache-inmemory@^1.5.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/apollo-cache-inmemory/-/apollo-cache-inmemory-1.5.1.tgz#265d1ee67b0bf0aca9c37629d410bfae44e62953"
......@@ -1170,29 +1155,16 @@ apollo-link-dedup@^1.0.0:
dependencies:
apollo-link "^1.2.3"
apollo-link-error@^1.0.3:
version "1.1.1"
resolved "https://registry.yarnpkg.com/apollo-link-error/-/apollo-link-error-1.1.1.tgz#69d7124d4dc11ce60f505c940f05d4f1aa0945fb"
integrity sha512-/yPcaQWcBdB94vpJ4FsiCJt1dAGGRm+6Tsj3wKwP+72taBH+UsGRQQZk7U/1cpZwl1yqhHZn+ZNhVOebpPcIlA==
apollo-link-http-common@^0.2.8:
version "0.2.13"
resolved "https://registry.yarnpkg.com/apollo-link-http-common/-/apollo-link-http-common-0.2.13.tgz#c688f6baaffdc7b269b2db7ae89dae7c58b5b350"
integrity sha512-Uyg1ECQpTTA691Fwx5e6Rc/6CPSu4TB4pQRTGIpwZ4l5JDOQ+812Wvi/e3IInmzOZpwx5YrrOfXrtN8BrsDXoA==
dependencies:
apollo-link "^1.2.3"
apollo-link-http-common@^0.2.5:
version "0.2.5"
resolved "https://registry.yarnpkg.com/apollo-link-http-common/-/apollo-link-http-common-0.2.5.tgz#d094beb7971523203359bf830bfbfa7b4e7c30ed"
integrity sha512-6FV1wr5AqAyJ64Em1dq5hhGgiyxZE383VJQmhIoDVc3MyNcFL92TkhxREOs4rnH2a9X2iJMko7nodHSGLC6d8w==
dependencies:
apollo-link "^1.2.3"
apollo-link-http@^1.3.1:
version "1.5.5"
resolved "https://registry.yarnpkg.com/apollo-link-http/-/apollo-link-http-1.5.5.tgz#7dbe851821771ad67fa29e3900c57f38cbd80da8"
integrity sha512-C5N6N/mRwmepvtzO27dgMEU3MMtRKSqcljBkYNZmWwH11BxkUQ5imBLPM3V4QJXNE7NFuAQAB5PeUd4ligivTQ==
dependencies:
apollo-link "^1.2.3"
apollo-link-http-common "^0.2.5"
apollo-link "^1.2.11"
ts-invariant "^0.3.2"
tslib "^1.9.3"
apollo-link@^1.0.0, apollo-link@^1.0.6, apollo-link@^1.2.3:
apollo-link@^1.0.0, apollo-link@^1.2.3:
version "1.2.3"
resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-1.2.3.tgz#9bd8d5fe1d88d31dc91dae9ecc22474d451fb70d"
integrity sha512-iL9yS2OfxYhigme5bpTbmRyC+Htt6tyo2fRMHT3K1XRL/C5IQDDz37OjpPy4ndx7WInSvfSZaaOTKFja9VWqSw==
......@@ -1200,6 +1172,25 @@ apollo-link@^1.0.0, apollo-link@^1.0.6, apollo-link@^1.2.3:
apollo-utilities "^1.0.0"
zen-observable-ts "^0.8.10"
apollo-link@^1.2.11, apollo-link@^1.2.6:
version "1.2.11"
resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-1.2.11.tgz#493293b747ad3237114ccd22e9f559e5e24a194d"
integrity sha512-PQvRCg13VduLy3X/0L79M6uOpTh5iHdxnxYuo8yL7sJlWybKRJwsv4IcRBJpMFbChOOaHY7Og9wgPo6DLKDKDA==
dependencies:
apollo-utilities "^1.2.1"
ts-invariant "^0.3.2"
tslib "^1.9.3"
zen-observable-ts "^0.8.18"
apollo-upload-client@^10.0.0:
version "10.0.0"
resolved "https://registry.yarnpkg.com/apollo-upload-client/-/apollo-upload-client-10.0.0.tgz#6cc3d0ea2aef40bc237b655f5042809cacee1859"
integrity sha512-N0SENiEkZXoY4nl9xxrXFcj/cL0AVkSNQ4aYXSaruCBWE0aKpK6aCe4DBmiEHrK3FAsMxZPEJxBRIWNbsXT8dw==
dependencies:
apollo-link "^1.2.6"
apollo-link-http-common "^0.2.8"
extract-files "^5.0.0"
apollo-utilities@1.2.1, apollo-utilities@^1.0.0, apollo-utilities@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-1.2.1.tgz#1c3a1ebf5607d7c8efe7636daaf58e7463b41b3c"
......@@ -4134,6 +4125,11 @@ extglob@^2.0.4:
snapdragon "^0.8.1"
to-regex "^3.0.1"
extract-files@^5.0.0:
version "5.0.1"
resolved "https://registry.yarnpkg.com/extract-files/-/extract-files-5.0.1.tgz#c9492a8410be643e260a376f0151361993d5f659"
integrity sha512-qRW6y9eKF0VbCyOoOEtFhzJ3uykAw8GKwQVXyAIqwocyEWW4m+v+evec34RwtUkkxxHh7NKBLJ6AnXM8W4dH5w==
extract-from-css@^0.4.4:
version "0.4.4"
resolved "https://registry.yarnpkg.com/extract-from-css/-/extract-from-css-0.4.4.tgz#1ea7df2e7c7c6eb9922fa08e8adaea486f6f8f92"
......@@ -4778,7 +4774,7 @@ graphlibrary@^2.2.0:
dependencies:
lodash "^4.17.5"
graphql-tag@^2.10.0, graphql-tag@^2.4.2:
graphql-tag@^2.10.0:
version "2.10.0"
resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.10.0.tgz#87da024be863e357551b2b8700e496ee2d4353ae"
integrity sha512-9FD6cw976TLLf9WYIUPCaaTpniawIjHWZSwIRZSjrfufJamcXbVVYfN2TWvJYbw0Xf2JjYbl1/f2+wDnBVw3/w==
......@@ -10460,6 +10456,13 @@ ts-invariant@^0.2.1:
dependencies:
tslib "^1.9.3"
ts-invariant@^0.3.2:
version "0.3.2"
resolved "https://registry.yarnpkg.com/ts-invariant/-/ts-invariant-0.3.2.tgz#89a2ffeb70879b777258df1df1c59383c35209b0"
integrity sha512-QsY8BCaRnHiB5T6iE4DPlJMAKEG3gzMiUco9FEt1jUXQf0XP6zi0idT0i0rMTu8A326JqNSDsmlkA9dRSh1TRg==
dependencies:
tslib "^1.9.3"
ts-jest@24.0.0, ts-jest@^23.10.5:
version "24.0.0"
resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-24.0.0.tgz#3f26bf2ec1fa584863a5a9c29bd8717d549efbf6"
......@@ -11540,6 +11543,14 @@ zen-observable-ts@^0.8.10:
dependencies:
zen-observable "^0.8.0"
zen-observable-ts@^0.8.18:
version "0.8.18"
resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-0.8.18.tgz#ade44b1060cc4a800627856ec10b9c67f5f639c8"
integrity sha512-q7d05s75Rn1j39U5Oapg3HI2wzriVwERVo4N7uFGpIYuHB9ff02P/E92P9B8T7QVC93jCMHpbXH7X0eVR5LA7A==
dependencies:
tslib "^1.9.3"
zen-observable "^0.8.0"
zen-observable@^0.8.0:
version "0.8.11"
resolved "https://registry.yarnpkg.com/zen-observable/-/zen-observable-0.8.11.tgz#d3415885eeeb42ee5abb9821c95bb518fcd6d199"
......
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