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",
|
"@babel/runtime": "^7.5.4",
|
||||||
"@iam4x/cypress-graphql-mock": "0.0.1",
|
"@iam4x/cypress-graphql-mock": "0.0.1",
|
||||||
"@vue/composition-api": "^1.4.2",
|
"@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",
|
"appolo": "^6.0.19",
|
||||||
"autoprefixer": "^7.1.2",
|
"autoprefixer": "^7.1.2",
|
||||||
"babel-helper-vue-jsx-merge-props": "^2.0.3",
|
"babel-helper-vue-jsx-merge-props": "^2.0.3",
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {INTERDISCIPLINARY, LANGUAGE_COMMUNICATION, SOCIETY} from '@/consts/instrument.consts';
|
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');
|
const ChevronRight = () => import(/* webpackChunkName: "icons" */'@/components/icons/ChevronRight');
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
@ -61,7 +61,6 @@
|
||||||
}
|
}
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
const [_, identifier] = this.instrumentFilter.currentFilter.split(':');
|
const [_, identifier] = this.instrumentFilter.currentFilter.split(':');
|
||||||
console.log(identifier, this.type);
|
|
||||||
return this.type === identifier;
|
return this.type === identifier;
|
||||||
},
|
},
|
||||||
typeClass() {
|
typeClass() {
|
||||||
|
|
|
||||||
|
|
@ -26,8 +26,7 @@
|
||||||
import FilterEntry from '@/components/instruments/FilterEntry';
|
import FilterEntry from '@/components/instruments/FilterEntry';
|
||||||
|
|
||||||
import SET_FILTER_MUTATION from 'gql/local/mutations/setInstrumentFilter.gql';
|
import SET_FILTER_MUTATION from 'gql/local/mutations/setInstrumentFilter.gql';
|
||||||
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 {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
|
|
@ -46,7 +45,6 @@
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
FilterEntry,
|
FilterEntry,
|
||||||
ChevronRight,
|
|
||||||
},
|
},
|
||||||
|
|
||||||
apollo: {
|
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 {onError} from '@apollo/client/link/error';
|
||||||
import {createHttpLink} from 'apollo-link-http';
|
import {
|
||||||
import {onError} from 'apollo-link-error';
|
ApolloClient,
|
||||||
import {ApolloClient} from 'apollo-client';
|
ApolloLink,
|
||||||
import {ApolloLink, Observable} from 'apollo-link';
|
createHttpLink,
|
||||||
|
} from '@apollo/client/core';
|
||||||
import fetch from 'unfetch';
|
import fetch from 'unfetch';
|
||||||
import {typeDefs} from '@/graphql/typedefs';
|
import {typeDefs} from '@/graphql/typedefs';
|
||||||
import {resolvers} from '@/graphql/resolvers';
|
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) {
|
export default function (uri, networkErrorCallback) {
|
||||||
const httpLink = createHttpLink({
|
const httpLink = createHttpLink({
|
||||||
|
|
@ -44,11 +22,10 @@ export default function (uri, networkErrorCallback) {
|
||||||
});
|
});
|
||||||
|
|
||||||
const consoleLink = new ApolloLink((operation, forward) => {
|
const consoleLink = new ApolloLink((operation, forward) => {
|
||||||
// console.log(`starting request for ${operation.operationName}`);
|
console.log('operation', operation);
|
||||||
|
|
||||||
return forward(operation).map((data) => {
|
|
||||||
// console.log(`ending request for ${operation.operationName}`);
|
|
||||||
|
|
||||||
|
return forward(operation).map(data => {
|
||||||
|
console.log('data', data);
|
||||||
return data;
|
return data;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -66,10 +43,11 @@ export default function (uri, networkErrorCallback) {
|
||||||
return forward(operation);
|
return forward(operation);
|
||||||
});
|
});
|
||||||
|
|
||||||
const errorLink = onError(({response, operation, networkError, graphQLErrors}) => {
|
const errorLink = onError(({networkError, graphQLErrors, forward, operation}) => {
|
||||||
|
// const observable = forward(operation);
|
||||||
if (networkError && networkErrorCallback) {
|
if (networkError && networkErrorCallback) {
|
||||||
networkErrorCallback(networkError.statusCode);
|
networkErrorCallback(networkError.statusCode);
|
||||||
return Observable.of();
|
// return observable;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (graphQLErrors) {
|
if (graphQLErrors) {
|
||||||
|
|
@ -85,68 +63,23 @@ export default function (uri, networkErrorCallback) {
|
||||||
*/
|
*/
|
||||||
if (networkError && networkError.name === 'ServerParseError') {
|
if (networkError && networkError.name === 'ServerParseError') {
|
||||||
// workaround found here: https://github.com/apollographql/apollo-link/issues/855#issuecomment-485764697
|
// 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 composedLink = ApolloLink.from([
|
||||||
|
consoleLink,
|
||||||
const cache = new InMemoryCache({
|
createOmitTypenameLink,
|
||||||
dataIdFromObject: obj => {
|
errorLink,
|
||||||
switch (obj.__typename) {
|
httpLink
|
||||||
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);
|
|
||||||
|
|
||||||
// Create the apollo client
|
// Create the apollo client
|
||||||
const client = new ApolloClient({
|
return new ApolloClient({
|
||||||
link: composedLink,
|
link: composedLink,
|
||||||
// link: httpLink,
|
|
||||||
cache,
|
cache,
|
||||||
connectToDevTools: true,
|
connectToDevTools: true,
|
||||||
typeDefs,
|
typeDefs,
|
||||||
resolvers,
|
resolvers,
|
||||||
});
|
});
|
||||||
client.onResetStore(() => {
|
|
||||||
writeLocalCache(cache);
|
|
||||||
});
|
|
||||||
return client;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,39 +1,48 @@
|
||||||
import SCROLL_POSITION from '@/graphql/gql/local/scrollPosition.gql';
|
import SCROLL_POSITION from '@/graphql/gql/local/scrollPosition.gql';
|
||||||
import HELLO_EMAIL from '@/graphql/gql/local/helloEmail.gql';
|
import HELLO_EMAIL from '@/graphql/gql/local/helloEmail.gql';
|
||||||
import SIDEBAR from '@/graphql/gql/local/sidebar.gql';
|
import {
|
||||||
import INSTRUMENT_FILTER from '@/graphql/gql/local/instrumentFiler.gql';
|
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 = {
|
export const resolvers = {
|
||||||
Mutation: {
|
Mutation: {
|
||||||
scrollTo: (_, {scrollTo}, {cache}) => {
|
scrollTo: (_, {scrollTo}) => {
|
||||||
const data = cache.readQuery({query: SCROLL_POSITION});
|
scrollToElementVar(scrollTo);
|
||||||
data.scrollPosition.scrollTo = scrollTo;
|
return {
|
||||||
cache.writeQuery({query: SCROLL_POSITION, data});
|
scrollTo: scrollToElementVar()
|
||||||
return data.scrollPosition;
|
};
|
||||||
},
|
},
|
||||||
helloEmail: (_, {email}, {cache}) => {
|
helloEmail: (_, {email}) => {
|
||||||
const data = cache.readQuery({query: HELLO_EMAIL});
|
helloEmailVar(email);
|
||||||
data.helloEmail.email = email;
|
return {
|
||||||
cache.writeQuery({query: HELLO_EMAIL, data});
|
email: helloEmailVar()
|
||||||
return data.helloEmail;
|
};
|
||||||
},
|
},
|
||||||
setInstrumentFilter: (_, {filter}, {cache}) => {
|
setInstrumentFilter: (_, {filter}) => {
|
||||||
const data = cache.readQuery({query: INSTRUMENT_FILTER});
|
currentFilterVar(filter);
|
||||||
data.instrumentFilter.currentFilter = filter;
|
return {
|
||||||
cache.writeQuery({query: INSTRUMENT_FILTER, data});
|
currentFilter: currentFilterVar()
|
||||||
return data.instrumentFilter;
|
};
|
||||||
},
|
},
|
||||||
toggleSidebar: (_, {sidebar: {profile, navigation}}, {cache}) => {
|
toggleSidebar: (_, {sidebar: {profile, navigation}}) => {
|
||||||
const data = cache.readQuery({query: SIDEBAR});
|
|
||||||
if (typeof profile !== 'undefined') {
|
if (typeof profile !== 'undefined') {
|
||||||
data.sidebar.profile = profile;
|
showProfileSidebarVar(profile);
|
||||||
}
|
}
|
||||||
if (typeof navigation !== 'undefined') {
|
if (typeof navigation !== 'undefined') {
|
||||||
data.sidebar.navigation = navigation;
|
showNavigationSidebarVar(navigation);
|
||||||
}
|
}
|
||||||
cache.writeQuery({query: SIDEBAR, data});
|
return {
|
||||||
return data.sidebar;
|
navigation: showNavigationSidebarVar(),
|
||||||
|
profile: showProfileSidebarVar()
|
||||||
|
};
|
||||||
},
|
},
|
||||||
|
// todo: does this still work?
|
||||||
deleteModuleNodes: (_, _query, {cache}) => {
|
deleteModuleNodes: (_, _query, {cache}) => {
|
||||||
Object.keys(cache.data.data)
|
Object.keys(cache.data.data)
|
||||||
.filter(prop => prop.indexOf('ModuleNode:') === 0)
|
.filter(prop => prop.indexOf('ModuleNode:') === 0)
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ export default {
|
||||||
|
|
||||||
apollo: {
|
apollo: {
|
||||||
sidebar: {
|
sidebar: {
|
||||||
query: SIDEBAR
|
query: SIDEBAR,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -56,8 +56,7 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "@/styles/_variables.scss";
|
@import "~styles/helpers";
|
||||||
@import "@/styles/_functions.scss";
|
|
||||||
|
|
||||||
.instrument {
|
.instrument {
|
||||||
&__title {
|
&__title {
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,7 @@
|
||||||
import InstrumentFilter from '@/components/instruments/InstrumentFilter';
|
import InstrumentFilter from '@/components/instruments/InstrumentFilter';
|
||||||
import InstrumentEntry from '@/components/instruments/InstrumentEntry';
|
import InstrumentEntry from '@/components/instruments/InstrumentEntry';
|
||||||
import INSTRUMENTS_QUERY from '@/graphql/gql/queries/instrumentsQuery.gql';
|
import INSTRUMENTS_QUERY from '@/graphql/gql/queries/instrumentsQuery.gql';
|
||||||
|
import INSTRUMENT_FILTER_QUERY from 'gql/local/instrumentFilter.gql';
|
||||||
import INSTRUMENT_FILTER_QUERY from 'gql/local/instrumentFiler.gql';
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
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: {
|
apollo: {
|
||||||
module() {
|
module() {
|
||||||
return {
|
return {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue