diff --git a/client/src/graphql/client.js b/client/src/graphql/client.js index 78b35863..cca47bb2 100644 --- a/client/src/graphql/client.js +++ b/client/src/graphql/client.js @@ -9,6 +9,7 @@ import {typeDefs} from '@/graphql/typedefs'; import {resolvers} from '@/graphql/resolvers'; import cache from './cache'; +import {router} from '@/router'; export default function (uri, networkErrorCallback) { const httpLink = createHttpLink({ @@ -64,19 +65,37 @@ export default function (uri, networkErrorCallback) { } }); + const notFoundLink = new ApolloLink((operation, forward) => { + return forward(operation).map(response => { + const {data} = response; + if (data) { + if (data.topic && data.topic.__typename === 'NotFound') { + // redirect to general 404 page. + // todo: specific topic not found page, with navigation? + router.push({ + name: 'not-found' + }); + } + } + return response; + }); + }); + let composedLink; if (process.env.NODE_ENV === 'production') { composedLink = ApolloLink.from([ createOmitTypenameLink, errorLink, - httpLink + notFoundLink, + httpLink, ]); } else { composedLink = ApolloLink.from([ consoleLink, createOmitTypenameLink, errorLink, - httpLink + notFoundLink, + httpLink, ]); } diff --git a/client/src/graphql/gql/fragments/notFoundParts.gql b/client/src/graphql/gql/fragments/notFoundParts.gql new file mode 100644 index 00000000..75febb60 --- /dev/null +++ b/client/src/graphql/gql/fragments/notFoundParts.gql @@ -0,0 +1,3 @@ +fragment NotFoundParts on NotFound { + reason +} diff --git a/client/src/graphql/gql/queries/topicQuery.gql b/client/src/graphql/gql/queries/topicQuery.gql index 0537b5f3..37bce375 100644 --- a/client/src/graphql/gql/queries/topicQuery.gql +++ b/client/src/graphql/gql/queries/topicQuery.gql @@ -1,6 +1,8 @@ #import "../fragments/topicParts.gql" +#import "../fragments/notFoundParts.gql" query Topic($slug: String!){ topic(slug: $slug) { ...TopicParts + ...NotFoundParts } } diff --git a/client/src/pages/topic-page.vue b/client/src/pages/topic-page.vue index 4bb85519..47acb63c 100644 --- a/client/src/pages/topic-page.vue +++ b/client/src/pages/topic-page.vue @@ -63,7 +63,7 @@ BookTopicNavigation, ModuleTeaser, PlayIcon, - BulbIcon + BulbIcon, }, apollo: { @@ -71,7 +71,7 @@ return { query: TOPIC_QUERY, variables: { - slug: this.$route.params.topicSlug + slug: this.$route.params.topicSlug, }, update(data) { return this.$getRidOfEdges(data).topic || {}; @@ -81,26 +81,26 @@ this.saveMe = false; this.updateLastVisitedTopic(this.topic.id); } - } + }, }; - } + }, }, data() { return { topic: { modules: { - edges: [] - } + edges: [], + }, }, - saveMe: false + saveMe: false, }; }, computed: { modules() { return this.topic.modules; - } + }, }, mounted() { @@ -116,12 +116,15 @@ this.$store.dispatch('showFullscreenVideo', this.topic.vimeoId); }, updateLastVisitedTopic(topicId) { + if (!topicId) { + return; + } this.$apollo.mutate({ mutation: UPDATE_LAST_TOPIC_MUTATION, variables: { input: { - id: topicId - } + id: topicId, + }, }, update(store, {data: {updateLastTopic: {topic}}}) { if (topic) { @@ -131,15 +134,15 @@ const data = { me: { ...me, - lastTopic: topic - } + lastTopic: topic, + }, }; store.writeQuery({query, data}); } } - } + }, }); - } + }, }, }; diff --git a/client/src/router/index.js b/client/src/router/index.js index 55ce0676..20d61063 100644 --- a/client/src/router/index.js +++ b/client/src/router/index.js @@ -33,11 +33,18 @@ const submission = () => import('@/pages/studentSubmission'); const postLoginRedirectUrlKey = 'postLoginRedirectionUrl'; +const notFoundRoute = { + component: p404, + meta: { + layout: 'blank', + }, +}; + const routes = [ { path: '/', name: 'home', - component: start + component: start, }, ...moduleRoutes, ...authRoutes, @@ -85,15 +92,17 @@ const routes = [ default: return '/unknown-auth-error'; } - } + }, }, {path: '/styleguide', component: styleGuidePage}, + { + path: '/not-found', + name: 'not-found', + ...notFoundRoute + }, { path: '*', - component: p404, - meta: { - layout: 'blank', - }, + ...notFoundRoute }, ];