Update apollo version, replace local state handling
This commit is contained in:
parent
5b105958e2
commit
a85296a628
|
|
@ -34,11 +34,6 @@
|
|||
"@babel/runtime": "^7.5.4",
|
||||
"@iam4x/cypress-graphql-mock": "0.0.1",
|
||||
"@vue/composition-api": "^1.4.2",
|
||||
"apollo-cache-inmemory": "^1.6.5",
|
||||
"apollo-client": "^2.6.8",
|
||||
"apollo-link": "^1.2.13",
|
||||
"apollo-link-error": "^1.1.12",
|
||||
"apollo-link-http": "^1.5.16",
|
||||
"appolo": "^6.0.19",
|
||||
"autoprefixer": "^7.1.2",
|
||||
"babel-helper-vue-jsx-merge-props": "^2.0.3",
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
<script>
|
||||
import {INTERDISCIPLINARY, LANGUAGE_COMMUNICATION, SOCIETY} from '@/consts/instrument.consts';
|
||||
import INSTRUMENT_FILTER_QUERY from 'gql/local/instrumentFiler.gql';
|
||||
import INSTRUMENT_FILTER_QUERY from 'gql/local/instrumentFilter.gql';
|
||||
const ChevronRight = () => import(/* webpackChunkName: "icons" */'@/components/icons/ChevronRight');
|
||||
|
||||
export default {
|
||||
|
|
@ -61,7 +61,6 @@
|
|||
}
|
||||
// eslint-disable-next-line
|
||||
const [_, identifier] = this.instrumentFilter.currentFilter.split(':');
|
||||
console.log(identifier, this.type);
|
||||
return this.type === identifier;
|
||||
},
|
||||
typeClass() {
|
||||
|
|
|
|||
|
|
@ -26,8 +26,7 @@
|
|||
import FilterEntry from '@/components/instruments/FilterEntry';
|
||||
|
||||
import SET_FILTER_MUTATION from 'gql/local/mutations/setInstrumentFilter.gql';
|
||||
import INSTRUMENT_FILTER_QUERY from 'gql/local/instrumentFiler.gql';
|
||||
const ChevronRight = () => import(/* webpackChunkName: "icons" */'@/components/icons/ChevronRight');
|
||||
import INSTRUMENT_FILTER_QUERY from 'gql/local/instrumentFilter.gql';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
|
|
@ -46,7 +45,6 @@
|
|||
},
|
||||
components: {
|
||||
FilterEntry,
|
||||
ChevronRight,
|
||||
},
|
||||
|
||||
apollo: {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,104 @@
|
|||
import {makeVar, defaultDataIdFromObject, InMemoryCache} from '@apollo/client/core';
|
||||
|
||||
const showNavigationSidebarVar = makeVar(false);
|
||||
const showProfileSidebarVar = makeVar(false);
|
||||
const scrollToElementVar = makeVar('');
|
||||
const currentFilterVar = makeVar('');
|
||||
const helloEmailVar = makeVar('');
|
||||
|
||||
const typePolicies = {
|
||||
// https://www.apollographql.com/docs/react/local-state/managing-state-with-field-policies/#example
|
||||
Query: {
|
||||
fields: {
|
||||
sidebar: {
|
||||
read() {
|
||||
return {
|
||||
profile: showProfileSidebarVar(),
|
||||
navigation: showNavigationSidebarVar()
|
||||
};
|
||||
}
|
||||
} ,
|
||||
scrollPosition: {
|
||||
read() {
|
||||
return {
|
||||
scrollTo: scrollToElementVar()
|
||||
};
|
||||
}
|
||||
},
|
||||
instrumentFilter: {
|
||||
read() {
|
||||
return {
|
||||
currentFilter: currentFilterVar()
|
||||
};
|
||||
}
|
||||
},
|
||||
helloEmail: {
|
||||
read() {
|
||||
return {
|
||||
email: helloEmailVar()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
};
|
||||
const cache = new InMemoryCache({
|
||||
// used to 'override' the behavior in resolving different types. We use it for local state management
|
||||
// https://www.apollographql.com/docs/react/local-state/managing-state-with-field-policies/#example
|
||||
typePolicies,
|
||||
// todo: document what this does, or link the doc for it at least
|
||||
dataIdFromObject: obj => {
|
||||
switch (obj.__typename) {
|
||||
case 'InstrumentNode':
|
||||
case 'ModuleNode':
|
||||
case 'RoomEntryNode':
|
||||
return `${obj.__typename}:${obj.slug}`;
|
||||
default:
|
||||
return defaultDataIdFromObject(obj);
|
||||
}
|
||||
},
|
||||
// todo: document what this does, or link the doc for it at least
|
||||
cacheRedirects: {
|
||||
Query: {
|
||||
contentBlock: (_, args, {getCacheKey}) => getCacheKey({__typename: 'ContentBlockNode', id: args.id}),
|
||||
chapter: (_, args, {getCacheKey}) => getCacheKey({__typename: 'ChapterNode', id: args.id}),
|
||||
assignment: (_, args, {getCacheKey}) => getCacheKey({__typename: 'AssignmentNode', id: args.id}),
|
||||
objective: (_, args, {getCacheKey}) => getCacheKey({__typename: 'ObjectiveNode', id: args.id}),
|
||||
objectiveGroup: (_, args, {getCacheKey}) => getCacheKey({__typename: 'ObjectiveGroupNode', id: args.id}),
|
||||
projectEntry: (_, args, {getCacheKey}) => getCacheKey({__typename: 'ProjectEntryNode', id: args.id}),
|
||||
project: (_, args, {getCacheKey}) => {
|
||||
if (args.slug) {
|
||||
return getCacheKey({__typename: 'ProjectNode', id: args.slug});
|
||||
} else {
|
||||
return getCacheKey({__typename: 'ProjectNode', id: args.id});
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// TODO: Monkey-patching in a fix for an open issue suggesting that
|
||||
// `readQuery` should return null or undefined if the query is not yet in the
|
||||
// cache: https://github.com/apollographql/apollo-feature-requests/issues/1
|
||||
// probably not needed any more, as per https://github.com/apollographql/apollo-client/pull/7098
|
||||
// cache.originalReadQuery = cache.readQuery;
|
||||
// cache.readQuery = (...args) => {
|
||||
// try {
|
||||
// return cache.originalReadQuery(...args);
|
||||
// } catch (err) {
|
||||
// console.error(err);
|
||||
// return undefined;
|
||||
// }
|
||||
// };
|
||||
|
||||
|
||||
export {
|
||||
showProfileSidebarVar,
|
||||
showNavigationSidebarVar,
|
||||
scrollToElementVar,
|
||||
currentFilterVar,
|
||||
helloEmailVar,
|
||||
cache
|
||||
};
|
||||
export default cache;
|
||||
|
|
@ -1,36 +1,14 @@
|
|||
import {defaultDataIdFromObject, InMemoryCache} from 'apollo-cache-inmemory';
|
||||
import {createHttpLink} from 'apollo-link-http';
|
||||
import {onError} from 'apollo-link-error';
|
||||
import {ApolloClient} from 'apollo-client';
|
||||
import {ApolloLink, Observable} from 'apollo-link';
|
||||
import {onError} from '@apollo/client/link/error';
|
||||
import {
|
||||
ApolloClient,
|
||||
ApolloLink,
|
||||
createHttpLink,
|
||||
} from '@apollo/client/core';
|
||||
import fetch from 'unfetch';
|
||||
import {typeDefs} from '@/graphql/typedefs';
|
||||
import {resolvers} from '@/graphql/resolvers';
|
||||
import cache from './cache';
|
||||
|
||||
const writeLocalCache = cache => {
|
||||
// we use the cache as our local state
|
||||
cache.writeData({
|
||||
data: {
|
||||
scrollPosition: {
|
||||
__typename: 'ScrollPosition',
|
||||
scrollTo: '',
|
||||
},
|
||||
sidebar: {
|
||||
__typename: 'Sidebar',
|
||||
profile: false,
|
||||
navigation: false,
|
||||
},
|
||||
helloEmail: {
|
||||
__typename: 'HelloEmail',
|
||||
email: '',
|
||||
},
|
||||
instrumentFilter: {
|
||||
__typename: 'InstrumentFilter',
|
||||
currentFilter: 'abc'
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
export default function (uri, networkErrorCallback) {
|
||||
const httpLink = createHttpLink({
|
||||
|
|
@ -44,11 +22,10 @@ export default function (uri, networkErrorCallback) {
|
|||
});
|
||||
|
||||
const consoleLink = new ApolloLink((operation, forward) => {
|
||||
// console.log(`starting request for ${operation.operationName}`);
|
||||
|
||||
return forward(operation).map((data) => {
|
||||
// console.log(`ending request for ${operation.operationName}`);
|
||||
console.log('operation', operation);
|
||||
|
||||
return forward(operation).map(data => {
|
||||
console.log('data', data);
|
||||
return data;
|
||||
});
|
||||
});
|
||||
|
|
@ -66,10 +43,11 @@ export default function (uri, networkErrorCallback) {
|
|||
return forward(operation);
|
||||
});
|
||||
|
||||
const errorLink = onError(({response, operation, networkError, graphQLErrors}) => {
|
||||
const errorLink = onError(({networkError, graphQLErrors, forward, operation}) => {
|
||||
// const observable = forward(operation);
|
||||
if (networkError && networkErrorCallback) {
|
||||
networkErrorCallback(networkError.statusCode);
|
||||
return Observable.of();
|
||||
// return observable;
|
||||
}
|
||||
|
||||
if (graphQLErrors) {
|
||||
|
|
@ -85,68 +63,23 @@ export default function (uri, networkErrorCallback) {
|
|||
*/
|
||||
if (networkError && networkError.name === 'ServerParseError') {
|
||||
// workaround found here: https://github.com/apollographql/apollo-link/issues/855#issuecomment-485764697
|
||||
return Observable.of();
|
||||
// return observable;
|
||||
}
|
||||
});
|
||||
|
||||
const composedLink = ApolloLink.from([createOmitTypenameLink, consoleLink, errorLink, httpLink]);
|
||||
|
||||
const cache = new InMemoryCache({
|
||||
dataIdFromObject: obj => {
|
||||
switch (obj.__typename) {
|
||||
case 'InstrumentNode':
|
||||
case 'ModuleNode':
|
||||
case 'RoomEntryNode':
|
||||
return `${obj.__typename}:${obj.slug}`;
|
||||
default:
|
||||
return defaultDataIdFromObject(obj);
|
||||
}
|
||||
},
|
||||
cacheRedirects: {
|
||||
Query: {
|
||||
contentBlock: (_, args, {getCacheKey}) => getCacheKey({__typename: 'ContentBlockNode', id: args.id}),
|
||||
chapter: (_, args, {getCacheKey}) => getCacheKey({__typename: 'ChapterNode', id: args.id}),
|
||||
assignment: (_, args, {getCacheKey}) => getCacheKey({__typename: 'AssignmentNode', id: args.id}),
|
||||
objective: (_, args, {getCacheKey}) => getCacheKey({__typename: 'ObjectiveNode', id: args.id}),
|
||||
objectiveGroup: (_, args, {getCacheKey}) => getCacheKey({__typename: 'ObjectiveGroupNode', id: args.id}),
|
||||
projectEntry: (_, args, {getCacheKey}) => getCacheKey({__typename: 'ProjectEntryNode', id: args.id}),
|
||||
project: (_, args, {getCacheKey}) => {
|
||||
if (args.slug) {
|
||||
return getCacheKey({__typename: 'ProjectNode', id: args.slug});
|
||||
} else {
|
||||
return getCacheKey({__typename: 'ProjectNode', id: args.id});
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// TODO: Monkey-patching in a fix for an open issue suggesting that
|
||||
// `readQuery` should return null or undefined if the query is not yet in the
|
||||
// cache: https://github.com/apollographql/apollo-feature-requests/issues/1
|
||||
cache.originalReadQuery = cache.readQuery;
|
||||
cache.readQuery = (...args) => {
|
||||
try {
|
||||
return cache.originalReadQuery(...args);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
|
||||
writeLocalCache(cache);
|
||||
const composedLink = ApolloLink.from([
|
||||
consoleLink,
|
||||
createOmitTypenameLink,
|
||||
errorLink,
|
||||
httpLink
|
||||
]);
|
||||
|
||||
// Create the apollo client
|
||||
const client = new ApolloClient({
|
||||
return new ApolloClient({
|
||||
link: composedLink,
|
||||
// link: httpLink,
|
||||
cache,
|
||||
connectToDevTools: true,
|
||||
typeDefs,
|
||||
resolvers,
|
||||
});
|
||||
client.onResetStore(() => {
|
||||
writeLocalCache(cache);
|
||||
});
|
||||
return client;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,39 +1,48 @@
|
|||
import SCROLL_POSITION from '@/graphql/gql/local/scrollPosition.gql';
|
||||
import HELLO_EMAIL from '@/graphql/gql/local/helloEmail.gql';
|
||||
import SIDEBAR from '@/graphql/gql/local/sidebar.gql';
|
||||
import INSTRUMENT_FILTER from '@/graphql/gql/local/instrumentFiler.gql';
|
||||
import {
|
||||
currentFilterVar,
|
||||
helloEmailVar,
|
||||
scrollToElementVar,
|
||||
showNavigationSidebarVar,
|
||||
showProfileSidebarVar,
|
||||
} from '@/graphql/cache';
|
||||
|
||||
// todo: this probably can all be done with the apollo vars in the calling components, but that might need a rewrite of
|
||||
// the parts where the mutation is called and then read. But maybe it works by itself already
|
||||
export const resolvers = {
|
||||
Mutation: {
|
||||
scrollTo: (_, {scrollTo}, {cache}) => {
|
||||
const data = cache.readQuery({query: SCROLL_POSITION});
|
||||
data.scrollPosition.scrollTo = scrollTo;
|
||||
cache.writeQuery({query: SCROLL_POSITION, data});
|
||||
return data.scrollPosition;
|
||||
scrollTo: (_, {scrollTo}) => {
|
||||
scrollToElementVar(scrollTo);
|
||||
return {
|
||||
scrollTo: scrollToElementVar()
|
||||
};
|
||||
},
|
||||
helloEmail: (_, {email}, {cache}) => {
|
||||
const data = cache.readQuery({query: HELLO_EMAIL});
|
||||
data.helloEmail.email = email;
|
||||
cache.writeQuery({query: HELLO_EMAIL, data});
|
||||
return data.helloEmail;
|
||||
helloEmail: (_, {email}) => {
|
||||
helloEmailVar(email);
|
||||
return {
|
||||
email: helloEmailVar()
|
||||
};
|
||||
},
|
||||
setInstrumentFilter: (_, {filter}, {cache}) => {
|
||||
const data = cache.readQuery({query: INSTRUMENT_FILTER});
|
||||
data.instrumentFilter.currentFilter = filter;
|
||||
cache.writeQuery({query: INSTRUMENT_FILTER, data});
|
||||
return data.instrumentFilter;
|
||||
setInstrumentFilter: (_, {filter}) => {
|
||||
currentFilterVar(filter);
|
||||
return {
|
||||
currentFilter: currentFilterVar()
|
||||
};
|
||||
},
|
||||
toggleSidebar: (_, {sidebar: {profile, navigation}}, {cache}) => {
|
||||
const data = cache.readQuery({query: SIDEBAR});
|
||||
toggleSidebar: (_, {sidebar: {profile, navigation}}) => {
|
||||
if (typeof profile !== 'undefined') {
|
||||
data.sidebar.profile = profile;
|
||||
showProfileSidebarVar(profile);
|
||||
}
|
||||
if (typeof navigation !== 'undefined') {
|
||||
data.sidebar.navigation = navigation;
|
||||
showNavigationSidebarVar(navigation);
|
||||
}
|
||||
cache.writeQuery({query: SIDEBAR, data});
|
||||
return data.sidebar;
|
||||
return {
|
||||
navigation: showNavigationSidebarVar(),
|
||||
profile: showProfileSidebarVar()
|
||||
};
|
||||
},
|
||||
// todo: does this still work?
|
||||
deleteModuleNodes: (_, _query, {cache}) => {
|
||||
Object.keys(cache.data.data)
|
||||
.filter(prop => prop.indexOf('ModuleNode:') === 0)
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ export default {
|
|||
|
||||
apollo: {
|
||||
sidebar: {
|
||||
query: SIDEBAR
|
||||
query: SIDEBAR,
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -56,8 +56,7 @@
|
|||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "@/styles/_variables.scss";
|
||||
@import "@/styles/_functions.scss";
|
||||
@import "~styles/helpers";
|
||||
|
||||
.instrument {
|
||||
&__title {
|
||||
|
|
|
|||
|
|
@ -22,8 +22,7 @@
|
|||
import InstrumentFilter from '@/components/instruments/InstrumentFilter';
|
||||
import InstrumentEntry from '@/components/instruments/InstrumentEntry';
|
||||
import INSTRUMENTS_QUERY from '@/graphql/gql/queries/instrumentsQuery.gql';
|
||||
|
||||
import INSTRUMENT_FILTER_QUERY from 'gql/local/instrumentFiler.gql';
|
||||
import INSTRUMENT_FILTER_QUERY from 'gql/local/instrumentFilter.gql';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
|
|
|
|||
|
|
@ -35,15 +35,6 @@
|
|||
};
|
||||
},
|
||||
|
||||
created() {
|
||||
this.$log.debug('**** module.vue created ****');
|
||||
this.$log.debug(`||| module id ${this.module.id} |||`);
|
||||
},
|
||||
mounted() {
|
||||
this.$log.debug('**** module.vue mounted ****');
|
||||
this.$log.debug(`||| module id ${this.module.id} |||`);
|
||||
},
|
||||
|
||||
apollo: {
|
||||
module() {
|
||||
return {
|
||||
|
|
|
|||
Loading…
Reference in New Issue