Add frontend language setting to local cache

Relates to MS-758
This commit is contained in:
Ramon Wenger 2023-08-22 15:14:09 +02:00
parent 0ae86202c7
commit 81b2b41979
13 changed files with 229 additions and 77 deletions

View File

@ -1,6 +1,7 @@
{
"plugins": {
"postcss-import": {},
"postcss-nested": {},
"postcss-url": {},
"autoprefixer": {}
}

View File

@ -1,3 +1,11 @@
type ModuleNode {
inEditMode: Boolean!
}
type PrivateUserNode {
language: String
}
extend type Mutation {
setLanguage(language: String!): PrivateUserNode
}

View File

@ -97,6 +97,7 @@
"ora": "^1.2.0",
"portfinder": "^1.0.13",
"postcss-import": "^15.0.0",
"postcss-nested": "^6.0.1",
"postcss-url": "^10.1.3",
"prettier": "2.8.2",
"rimraf": "^2.6.0",

View File

@ -13,9 +13,11 @@ import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/
* Therefore it is highly recommended to use the babel or swc plugin for production.
*/
const documents = {
"\n query LanguageQuery {\n me {\n language @client\n }\n }\n ": types.LanguageQueryDocument,
"\n mutation SetLanguage($language: String!) {\n setLanguage(language: $language) @client {\n language\n }\n }\n ": types.SetLanguageDocument,
"\n query ReadOnlyQuery {\n me {\n readOnly\n selectedClass {\n readOnly\n }\n }\n }\n ": types.ReadOnlyQueryDocument,
"\n query ModuleTitleQuery($slug: String) {\n module(slug: $slug) {\n title\n }\n }\n ": types.ModuleTitleQueryDocument,
"\n fragment SnapshotListItem on SnapshotNode {\n id\n title\n created\n mine\n shared\n creator\n }\n": types.SnapshotListItemFragmentDoc,
"\n fragment SnapshotListItem on SnapshotNode {\n shared\n }\n": types.SnapshotListItemFragmentDoc,
"\n fragment SnapshotTitle on SnapshotNode {\n title\n }\n": types.SnapshotTitleFragmentDoc,
"\n query ModuleEditModeQuery($slug: String) {\n module(slug: $slug) {\n inEditMode @client\n slug\n }\n }\n": types.ModuleEditModeQueryDocument,
"\n query ChapterQuery($id: ID!) {\n chapter(id: $id) {\n path\n }\n }\n ": types.ChapterQueryDocument,
@ -38,6 +40,14 @@ const documents = {
*/
export function graphql(source: string): unknown;
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
export function graphql(source: "\n query LanguageQuery {\n me {\n language @client\n }\n }\n "): (typeof documents)["\n query LanguageQuery {\n me {\n language @client\n }\n }\n "];
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
export function graphql(source: "\n mutation SetLanguage($language: String!) {\n setLanguage(language: $language) @client {\n language\n }\n }\n "): (typeof documents)["\n mutation SetLanguage($language: String!) {\n setLanguage(language: $language) @client {\n language\n }\n }\n "];
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
@ -49,7 +59,7 @@ export function graphql(source: "\n query ModuleTitleQuery($slug: String) {\n
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
export function graphql(source: "\n fragment SnapshotListItem on SnapshotNode {\n id\n title\n created\n mine\n shared\n creator\n }\n"): (typeof documents)["\n fragment SnapshotListItem on SnapshotNode {\n id\n title\n created\n mine\n shared\n creator\n }\n"];
export function graphql(source: "\n fragment SnapshotListItem on SnapshotNode {\n shared\n }\n"): (typeof documents)["\n fragment SnapshotListItem on SnapshotNode {\n shared\n }\n"];
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/

View File

@ -824,6 +824,7 @@ export type Mutation = {
leaveTeam?: Maybe<LeaveTeam>;
logout?: Maybe<Logout>;
mutateContentBlock?: Maybe<MutateContentBlockPayload>;
setLanguage?: Maybe<PrivateUserNode>;
shareSnapshot?: Maybe<ShareSnapshotPayload>;
spellCheck?: Maybe<SpellCheckPayload>;
syncModuleVisibility?: Maybe<SyncModuleVisibilityPayload>;
@ -987,6 +988,11 @@ export type MutationMutateContentBlockArgs = {
};
export type MutationSetLanguageArgs = {
language: Scalars['String']['input'];
};
export type MutationShareSnapshotArgs = {
input: ShareSnapshotInput;
};
@ -1255,6 +1261,7 @@ export type PrivateUserNode = Node & {
firstName: Scalars['String']['output'];
id: Scalars['ID']['output'];
isTeacher?: Maybe<Scalars['Boolean']['output']>;
language?: Maybe<Scalars['String']['output']>;
lastModule?: Maybe<ModuleNode>;
lastName: Scalars['String']['output'];
lastTopic?: Maybe<TopicNode>;
@ -2269,6 +2276,18 @@ export type UserGroupBlockVisibility = {
schoolClassId: Scalars['ID']['input'];
};
export type LanguageQueryQueryVariables = Exact<{ [key: string]: never; }>;
export type LanguageQueryQuery = { __typename?: 'Query', me?: { __typename?: 'PrivateUserNode', language?: string | null } | null };
export type SetLanguageMutationVariables = Exact<{
language: Scalars['String']['input'];
}>;
export type SetLanguageMutation = { __typename?: 'Mutation', setLanguage?: { __typename?: 'PrivateUserNode', language?: string | null } | null };
export type ReadOnlyQueryQueryVariables = Exact<{ [key: string]: never; }>;
@ -2281,7 +2300,7 @@ export type ModuleTitleQueryQueryVariables = Exact<{
export type ModuleTitleQueryQuery = { __typename?: 'Query', module?: { __typename?: 'ModuleNode', title: string } | null };
export type SnapshotListItemFragment = { __typename?: 'SnapshotNode', id: string, title?: string | null, created: any, mine?: boolean | null, shared: boolean, creator: string } & { ' $fragmentName'?: 'SnapshotListItemFragment' };
export type SnapshotListItemFragment = { __typename?: 'SnapshotNode', shared: boolean } & { ' $fragmentName'?: 'SnapshotListItemFragment' };
export type SnapshotTitleFragment = { __typename?: 'SnapshotNode', title?: string | null } & { ' $fragmentName'?: 'SnapshotTitleFragment' };
@ -2323,12 +2342,14 @@ export type ModuleSolutionsQueryVariables = Exact<{
export type ModuleSolutionsQuery = { __typename?: 'Query', module?: { __typename?: 'ModuleNode', solutionsEnabled?: boolean | null, slug: string } | null };
export const SnapshotListItemFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SnapshotListItem"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SnapshotNode"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"created"}},{"kind":"Field","name":{"kind":"Name","value":"mine"}},{"kind":"Field","name":{"kind":"Name","value":"shared"}},{"kind":"Field","name":{"kind":"Name","value":"creator"}}]}}]} as unknown as DocumentNode<SnapshotListItemFragment, unknown>;
export const SnapshotListItemFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SnapshotListItem"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SnapshotNode"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"shared"}}]}}]} as unknown as DocumentNode<SnapshotListItemFragment, unknown>;
export const SnapshotTitleFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SnapshotTitle"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SnapshotNode"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"title"}}]}}]} as unknown as DocumentNode<SnapshotTitleFragment, unknown>;
export const LanguageQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"LanguageQuery"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"me"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"language"},"directives":[{"kind":"Directive","name":{"kind":"Name","value":"client"}}]}]}}]}}]} as unknown as DocumentNode<LanguageQueryQuery, LanguageQueryQueryVariables>;
export const SetLanguageDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"SetLanguage"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"language"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"setLanguage"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"language"},"value":{"kind":"Variable","name":{"kind":"Name","value":"language"}}}],"directives":[{"kind":"Directive","name":{"kind":"Name","value":"client"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"language"}}]}}]}}]} as unknown as DocumentNode<SetLanguageMutation, SetLanguageMutationVariables>;
export const ReadOnlyQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ReadOnlyQuery"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"me"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"readOnly"}},{"kind":"Field","name":{"kind":"Name","value":"selectedClass"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"readOnly"}}]}}]}}]}}]} as unknown as DocumentNode<ReadOnlyQueryQuery, ReadOnlyQueryQueryVariables>;
export const ModuleTitleQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ModuleTitleQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"slug"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"module"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"slug"},"value":{"kind":"Variable","name":{"kind":"Name","value":"slug"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"title"}}]}}]}}]} as unknown as DocumentNode<ModuleTitleQueryQuery, ModuleTitleQueryQueryVariables>;
export const ModuleEditModeQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ModuleEditModeQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"slug"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"module"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"slug"},"value":{"kind":"Variable","name":{"kind":"Name","value":"slug"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"inEditMode"},"directives":[{"kind":"Directive","name":{"kind":"Name","value":"client"}}]},{"kind":"Field","name":{"kind":"Name","value":"slug"}}]}}]}}]} as unknown as DocumentNode<ModuleEditModeQueryQuery, ModuleEditModeQueryQueryVariables>;
export const ChapterQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ChapterQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"chapter"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"path"}}]}}]}}]} as unknown as DocumentNode<ChapterQueryQuery, ChapterQueryQueryVariables>;
export const ContentBlockQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ContentBlockQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"contentBlock"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"path"}}]}}]}}]} as unknown as DocumentNode<ContentBlockQueryQuery, ContentBlockQueryQueryVariables>;
export const ModuleSnapshotsQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ModuleSnapshotsQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"slug"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"module"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"slug"},"value":{"kind":"Variable","name":{"kind":"Name","value":"slug"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"metaTitle"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"topic"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"title"}}]}},{"kind":"Field","name":{"kind":"Name","value":"snapshots"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"SnapshotListItem"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SnapshotListItem"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SnapshotNode"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"created"}},{"kind":"Field","name":{"kind":"Name","value":"mine"}},{"kind":"Field","name":{"kind":"Name","value":"shared"}},{"kind":"Field","name":{"kind":"Name","value":"creator"}}]}}]} as unknown as DocumentNode<ModuleSnapshotsQueryQuery, ModuleSnapshotsQueryQueryVariables>;
export const ModuleSnapshotsQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ModuleSnapshotsQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"slug"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"module"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"slug"},"value":{"kind":"Variable","name":{"kind":"Name","value":"slug"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"metaTitle"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"topic"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"title"}}]}},{"kind":"Field","name":{"kind":"Name","value":"snapshots"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"SnapshotListItem"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SnapshotListItem"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SnapshotNode"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"shared"}}]}}]} as unknown as DocumentNode<ModuleSnapshotsQueryQuery, ModuleSnapshotsQueryQueryVariables>;
export const ModuleSolutionsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ModuleSolutions"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"slug"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"module"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"slug"},"value":{"kind":"Variable","name":{"kind":"Name","value":"slug"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"solutionsEnabled"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}}]}}]}}]} as unknown as DocumentNode<ModuleSolutionsQuery, ModuleSolutionsQueryVariables>;

View File

@ -0,0 +1,74 @@
<template>
<div class="language-switcher">
<span>{{ language }} {{ language === 'de' }}</span>
<a
class="language-switcher__language"
:class="{ 'language-switcher__language--active': language === 'de' }"
@click="changeLanguage('de')"
>de</a
>
<a
class="language-switcher__language"
:class="{ 'language-switcher__language--active': language === 'en' }"
@click="changeLanguage('en')"
>en</a
>
<a
class="language-switcher__language"
:class="{ 'language-switcher__language--active': language === 'fr' }"
@click="changeLanguage('fr')"
>fr</a
>
</div>
</template>
<script setup lang="ts">
import { graphql } from '@/__generated__';
import { useMutation, useQuery } from '@vue/apollo-composable';
import { computed } from '@vue/reactivity';
const { result } = useQuery(
graphql(`
query LanguageQuery {
me {
language @client
}
}
`)
);
const language = computed(() => result.value?.me.language || '');
const { mutate: changeLanguageMutation } = useMutation(
graphql(`
mutation SetLanguage($language: String!) {
setLanguage(language: $language) @client {
language
}
}
`)
);
const changeLanguage = (lang: string) => changeLanguageMutation({ language: lang });
</script>
<style scoped lang="postcss">
.language-switcher {
border-radius: 30px;
border: 1px solid black;
display: inline-flex;
&__language {
text-transform: uppercase;
padding: 10px 20px;
border-right: 1px solid black;
&:last-child {
border-right: 0;
}
&--active {
color: red;
}
}
}
</style>

View File

@ -26,81 +26,79 @@
</template>
<script>
import Pill from "@/components/ui/Pill.vue";
import Pill from '@/components/ui/Pill.vue';
export default {
export default {
props: ['metaTitle', 'title', 'teaser', 'id', 'slug', 'heroImage', 'level', 'category', 'language'],
props: ['metaTitle', 'title', 'teaser', 'id', 'slug', 'heroImage', 'level', 'category'],
components: { Pill },
components: {Pill},
computed: {
moduleLink() {
if (this.slug) {
return {
name: 'module',
params: {
slug: this.slug,
},
};
} else {
return {};
}
},
computed: {
moduleLink() {
if (this.slug) {
return {
name: 'module',
params: {
slug: this.slug,
},
};
} else {
return {};
}
},
};
},
};
</script>
<style scoped lang="scss">
@import 'styles/helpers';
@import 'styles/helpers';
.module-teaser {
box-shadow: 0 3px 9px 0 rgba(0, 0, 0, 0.12);
border: 1px solid #e2e2e2;
height: 390px;
max-width: 380px;
width: 100%;
border-radius: 12px;
overflow: hidden;
box-sizing: border-box;
cursor: pointer;
.module-teaser {
box-shadow: 0 3px 9px 0 rgba(0, 0, 0, 0.12);
border: 1px solid #e2e2e2;
height: 390px;
max-width: 380px;
width: 100%;
border-radius: 12px;
overflow: hidden;
box-sizing: border-box;
cursor: pointer;
&--small {
height: 300px;
}
&__image {
width: 100%;
max-height: 150px;
height: 150px;
background-position: center;
background-size: 100% auto;
background-repeat: no-repeat;
}
&__body {
padding: 20px;
}
&__meta-title {
color: $color-silver-dark;
margin-bottom: $large-spacing;
@include regular-text;
}
&__title {
@include heading-3;
margin-bottom: 5px;
}
&__description {
line-height: $default-line-height;
font-size: 1.2rem;
}
&__pills {
margin-top: $medium-spacing;
}
&--small {
height: 300px;
}
&__image {
width: 100%;
max-height: 150px;
height: 150px;
background-position: center;
background-size: 100% auto;
background-repeat: no-repeat;
}
&__body {
padding: 20px;
}
&__meta-title {
color: $color-silver-dark;
margin-bottom: $large-spacing;
@include regular-text;
}
&__title {
@include heading-3;
margin-bottom: 5px;
}
&__description {
line-height: $default-line-height;
font-size: 1.2rem;
}
&__pills {
margin-top: $medium-spacing;
}
}
</style>

View File

@ -6,6 +6,7 @@ const showProfileSidebarVar = makeVar(false);
const scrollToElementVar = makeVar('');
const currentFilterVar = makeVar('');
const helloEmailVar = makeVar('');
const languageVar = makeVar('de');
const idToRefFactory =
(__typename) =>
@ -47,6 +48,16 @@ const typePolicies = {
},
keyFields: ['slug'],
},
PrivateUserNode: {
fields: {
language: {
read() {
console.log(`returning language ${languageVar()}`);
return languageVar();
},
},
},
},
RoomEntryNode: {
keyFields: ['slug'],
},
@ -131,5 +142,13 @@ const cache = new InMemoryCache({
// }
// };
export { showProfileSidebarVar, showNavigationSidebarVar, scrollToElementVar, currentFilterVar, helloEmailVar, cache };
export {
showProfileSidebarVar,
showNavigationSidebarVar,
scrollToElementVar,
currentFilterVar,
helloEmailVar,
languageVar,
cache,
};
export default cache;

View File

@ -8,6 +8,7 @@ fragment ModuleParts on ModuleNode {
heroImage
heroSource
solutionsEnabled
language
inEditMode @client
level {
id

View File

@ -4,6 +4,7 @@ import {
scrollToElementVar,
showNavigationSidebarVar,
showProfileSidebarVar,
languageVar,
} 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
@ -40,6 +41,12 @@ export const resolvers = {
profile: showProfileSidebarVar(),
};
},
setLanguage: (_, { language }) => {
languageVar(language);
return {
language: languageVar(),
};
},
// todo: does this still work?
deleteModuleNodes: (_, _query, { cache }) => {
Object.keys(cache.data.data)

View File

@ -27,9 +27,14 @@ export const typeDefs = gql`
inEditMode: Boolean!
}
extend type PrivateUserNode {
language: String
}
type Mutation {
scrollTo(scrollTo: String!): ScrollPosition
helloEmail(email: String!): HelloEmail
toggleSidebar(sidebar: SidebarInput!): Sidebar
setLanguage(language: String!): PrivateUserNode
}
`;

View File

@ -35,13 +35,17 @@
</a>
</div>
<div class="topic__modulefilter">
<module-filter :modules="modules" :me="me" v-if="modules.length > 0" ></module-filter>
<module-filter
:modules="modules"
:me="me"
v-if="modules.length > 0"
></module-filter>
</div>
</div>
</div>
</template>
<script>
<script lang="ts">
import ModuleFilter from '@/components/modules/ModuleFilter.vue';
import { defineAsyncComponent } from 'vue';
import TOPIC_QUERY from '@/graphql/gql/queries/topicQuery.gql';
@ -167,7 +171,6 @@ export default {
grid-template-columns: 300px 1fr;
}
&__navigation {
padding: 0 $medium-spacing;
display: none;
@ -207,6 +210,5 @@ export default {
&__link-description {
@include heading-3;
}
}
</style>

View File

@ -62,6 +62,7 @@ class ModuleNode(DjangoObjectType):
assignments = graphene.List(AssignmentNode)
level = graphene.Field(ModuleLevelNode)
category = graphene.Field(ModuleCategoryNode)
language = graphene.String()
def resolve_chapters(self, info, **kwargs):
return Chapter.get_by_parent(self)
@ -125,6 +126,10 @@ class ModuleNode(DjangoObjectType):
def resolve_assignments(parent: Module, info, **kwargs):
return parent.assignments.all()
@staticmethod
def resolve_language(parent: Module, info, **kwargs):
return parent.locale.language_code
class RecentModuleNode(DjangoObjectType):
class Meta: