Finish refactoring the Assignment component
This commit is contained in:
parent
cfb20c00c3
commit
8cd508ce31
|
|
@ -23,6 +23,8 @@ const documents = {
|
|||
"\n fragment AssignmentParts on AssignmentNode {\n id\n title\n assignment\n solution\n submission {\n ...SubmissionParts\n }\n }\n": types.AssignmentPartsFragmentDoc,
|
||||
"\n query AssignmentQuery($id: ID!) {\n assignment(id: $id) {\n ...AssignmentParts\n }\n }\n ": types.AssignmentQueryDocument,
|
||||
"\n mutation UpdateAssignment($input: UpdateAssignmentInput!) {\n updateAssignment(input: $input) {\n updatedAssignment {\n ...AssignmentParts\n }\n }\n }\n ": types.UpdateAssignmentDocument,
|
||||
"\n mutation UpdateAssignmentWithSuccess($input: UpdateAssignmentInput!) {\n updateAssignment(input: $input) {\n successful\n updatedAssignment {\n ...AssignmentParts\n }\n }\n }\n ": types.UpdateAssignmentWithSuccessDocument,
|
||||
"\n mutation SpellCheck($input: SpellCheckInput!) {\n spellCheck(input: $input) {\n correct\n results {\n sentence\n offset\n sentenceOffset\n length\n affected\n corrected\n }\n }\n }\n ": types.SpellCheckDocument,
|
||||
"\n fragment ModuleHighlightsFragment on ModuleNode {\n id\n __typename\n slug\n highlights {\n ...HighlightParts\n }\n }\n": types.ModuleHighlightsFragmentFragmentDoc,
|
||||
"\n fragment ModuleLevelFragment on ModuleLevelNode {\n name\n id\n filterAttributeType\n }\n": types.ModuleLevelFragmentFragmentDoc,
|
||||
"\n query ModuleFilterQuery {\n moduleLevels {\n ...ModuleLevelFragment\n }\n moduleCategories {\n name\n id\n filterAttributeType\n }\n me {\n language @client\n }\n }\n ": types.ModuleFilterQueryDocument,
|
||||
|
|
@ -36,6 +38,11 @@ const documents = {
|
|||
"\n mutation UpdateHighlight($input: UpdateHighlightInput!) {\n updateHighlight(input: $input) {\n highlight {\n ...HighlightParts\n }\n }\n }\n": types.UpdateHighlightDocument,
|
||||
"\n mutation AddHighlight($input: AddHighlightInput!) {\n addHighlight(input: $input) {\n __typename\n highlight {\n ...HighlightParts\n }\n }\n }\n": types.AddHighlightDocument,
|
||||
"\n mutation AddContentHighlight($input: AddContentHighlightInput!) {\n addContentHighlight(input: $input) {\n __typename\n highlight {\n ...HighlightParts\n }\n }\n }\n": types.AddContentHighlightDocument,
|
||||
"\n fragment SchoolClassParts on SchoolClassNode {\n id\n name\n }\n": types.SchoolClassPartsFragmentDoc,
|
||||
"\n fragment UserParts on PrivateUserNode {\n id\n pk\n username\n email\n firstName\n lastName\n avatarUrl\n expiryDate\n readOnly\n lastModuleLevel {\n id\n name\n filterAttributeType\n }\n lastModule {\n id\n slug\n }\n lastTopic {\n id\n slug\n }\n selectedClass {\n id\n readOnly\n }\n recentModules(orderBy: \"-visited\") {\n edges {\n node {\n ...ModuleParts\n }\n }\n }\n schoolClasses {\n ...SchoolClassParts\n }\n }\n": types.UserPartsFragmentDoc,
|
||||
"\n fragment TeamParts on TeamNode {\n name\n code\n id\n members {\n firstName\n lastName\n id\n isMe\n }\n }\n": types.TeamPartsFragmentDoc,
|
||||
"\n fragment ModuleParts on ModuleNode {\n id\n title\n metaTitle\n teaser\n intro\n slug\n heroImage\n heroSource\n solutionsEnabled\n highlights {\n ...HighlightParts\n }\n language\n inEditMode @client\n level {\n id\n name\n }\n category {\n id\n name\n }\n topic {\n slug\n title\n }\n bookmark {\n note {\n id\n text\n }\n }\n }\n": types.ModulePartsFragmentDoc,
|
||||
"\n query MeQuery {\n me {\n ...UserParts\n team {\n ...TeamParts\n }\n isTeacher\n permissions\n onboardingVisited\n }\n }\n ": types.MeQueryDocument,
|
||||
"\n fragment InstrumentHighlightsWithIdOnlyFragment on InstrumentNode {\n highlights {\n id\n }\n }\n ": types.InstrumentHighlightsWithIdOnlyFragmentFragmentDoc,
|
||||
"\n fragment ChapterHighlightsWithIdOnlyFragment on ChapterNode {\n highlights {\n id\n }\n }\n ": types.ChapterHighlightsWithIdOnlyFragmentFragmentDoc,
|
||||
"\n fragment ModuleHighlightsWithIdOnlyFragment on ModuleNode {\n highlights {\n id\n }\n }\n ": types.ModuleHighlightsWithIdOnlyFragmentFragmentDoc,
|
||||
|
|
@ -107,6 +114,14 @@ export function graphql(source: "\n query AssignmentQuery($id: ID!) {\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 UpdateAssignment($input: UpdateAssignmentInput!) {\n updateAssignment(input: $input) {\n updatedAssignment {\n ...AssignmentParts\n }\n }\n }\n "): (typeof documents)["\n mutation UpdateAssignment($input: UpdateAssignmentInput!) {\n updateAssignment(input: $input) {\n updatedAssignment {\n ...AssignmentParts\n }\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 UpdateAssignmentWithSuccess($input: UpdateAssignmentInput!) {\n updateAssignment(input: $input) {\n successful\n updatedAssignment {\n ...AssignmentParts\n }\n }\n }\n "): (typeof documents)["\n mutation UpdateAssignmentWithSuccess($input: UpdateAssignmentInput!) {\n updateAssignment(input: $input) {\n successful\n updatedAssignment {\n ...AssignmentParts\n }\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 SpellCheck($input: SpellCheckInput!) {\n spellCheck(input: $input) {\n correct\n results {\n sentence\n offset\n sentenceOffset\n length\n affected\n corrected\n }\n }\n }\n "): (typeof documents)["\n mutation SpellCheck($input: SpellCheckInput!) {\n spellCheck(input: $input) {\n correct\n results {\n sentence\n offset\n sentenceOffset\n length\n affected\n corrected\n }\n }\n }\n "];
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
|
|
@ -159,6 +174,26 @@ export function graphql(source: "\n mutation AddHighlight($input: AddHighlightI
|
|||
* 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 AddContentHighlight($input: AddContentHighlightInput!) {\n addContentHighlight(input: $input) {\n __typename\n highlight {\n ...HighlightParts\n }\n }\n }\n"): (typeof documents)["\n mutation AddContentHighlight($input: AddContentHighlightInput!) {\n addContentHighlight(input: $input) {\n __typename\n highlight {\n ...HighlightParts\n }\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 fragment SchoolClassParts on SchoolClassNode {\n id\n name\n }\n"): (typeof documents)["\n fragment SchoolClassParts on SchoolClassNode {\n id\n name\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 fragment UserParts on PrivateUserNode {\n id\n pk\n username\n email\n firstName\n lastName\n avatarUrl\n expiryDate\n readOnly\n lastModuleLevel {\n id\n name\n filterAttributeType\n }\n lastModule {\n id\n slug\n }\n lastTopic {\n id\n slug\n }\n selectedClass {\n id\n readOnly\n }\n recentModules(orderBy: \"-visited\") {\n edges {\n node {\n ...ModuleParts\n }\n }\n }\n schoolClasses {\n ...SchoolClassParts\n }\n }\n"): (typeof documents)["\n fragment UserParts on PrivateUserNode {\n id\n pk\n username\n email\n firstName\n lastName\n avatarUrl\n expiryDate\n readOnly\n lastModuleLevel {\n id\n name\n filterAttributeType\n }\n lastModule {\n id\n slug\n }\n lastTopic {\n id\n slug\n }\n selectedClass {\n id\n readOnly\n }\n recentModules(orderBy: \"-visited\") {\n edges {\n node {\n ...ModuleParts\n }\n }\n }\n schoolClasses {\n ...SchoolClassParts\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 fragment TeamParts on TeamNode {\n name\n code\n id\n members {\n firstName\n lastName\n id\n isMe\n }\n }\n"): (typeof documents)["\n fragment TeamParts on TeamNode {\n name\n code\n id\n members {\n firstName\n lastName\n id\n isMe\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 fragment ModuleParts on ModuleNode {\n id\n title\n metaTitle\n teaser\n intro\n slug\n heroImage\n heroSource\n solutionsEnabled\n highlights {\n ...HighlightParts\n }\n language\n inEditMode @client\n level {\n id\n name\n }\n category {\n id\n name\n }\n topic {\n slug\n title\n }\n bookmark {\n note {\n id\n text\n }\n }\n }\n"): (typeof documents)["\n fragment ModuleParts on ModuleNode {\n id\n title\n metaTitle\n teaser\n intro\n slug\n heroImage\n heroSource\n solutionsEnabled\n highlights {\n ...HighlightParts\n }\n language\n inEditMode @client\n level {\n id\n name\n }\n category {\n id\n name\n }\n topic {\n slug\n title\n }\n bookmark {\n note {\n id\n text\n }\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 query MeQuery {\n me {\n ...UserParts\n team {\n ...TeamParts\n }\n isTeacher\n permissions\n onboardingVisited\n }\n }\n "): (typeof documents)["\n query MeQuery {\n me {\n ...UserParts\n team {\n ...TeamParts\n }\n isTeacher\n permissions\n onboardingVisited\n }\n }\n "];
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -58,13 +58,18 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { nextTick, onMounted, ref, watch } from 'vue';
|
||||
import { defineAsyncComponent, nextTick, onMounted, ref, watch } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { useMutation, useQuery } from '@vue/apollo-composable';
|
||||
import { graphql } from '@/__generated__';
|
||||
import { HighlightNode } from '@/__generated__/graphql';
|
||||
import { computed } from '@vue/reactivity';
|
||||
import { markHighlight } from '@/helpers/highlight';
|
||||
import { sanitize } from '@/helpers/text';
|
||||
import { matomoTrackEvent } from '@/helpers/matomo-client';
|
||||
import { getMe } from '@/graphql/queries';
|
||||
import { PAGE_LOAD_TIMEOUT } from '@/consts/navigation.consts';
|
||||
import debounce from 'lodash/debounce';
|
||||
import Mark from 'mark.js';
|
||||
|
||||
export interface Props {
|
||||
|
|
@ -72,6 +77,10 @@ export interface Props {
|
|||
highlights: HighlightNode[];
|
||||
}
|
||||
|
||||
const SubmissionForm = defineAsyncComponent(() => import('@/components/content-blocks/assignment/SubmissionForm.vue'));
|
||||
const Solution = defineAsyncComponent(() => import('@/components/content-blocks/Solution.vue'));
|
||||
const SpellCheck = defineAsyncComponent(() => import('@/components/content-blocks/assignment/SpellCheck.vue'));
|
||||
|
||||
const route = useRoute();
|
||||
const assignmentDiv = ref<HTMLElement | null>(null);
|
||||
|
||||
|
|
@ -84,6 +93,9 @@ const initialSubmission = {
|
|||
};
|
||||
const assignment = ref({ submission: initialSubmission });
|
||||
const corrections = ref('');
|
||||
const unsaved = ref(false);
|
||||
const saving = ref(0);
|
||||
const spellcheckLoading = ref(false);
|
||||
|
||||
graphql(`
|
||||
fragment SubmissionParts on StudentSubmissionNode {
|
||||
|
|
@ -102,7 +114,7 @@ graphql(`
|
|||
}
|
||||
`);
|
||||
|
||||
graphql(`
|
||||
const assignmentFragment = graphql(`
|
||||
fragment AssignmentParts on AssignmentNode {
|
||||
id
|
||||
title
|
||||
|
|
@ -114,6 +126,8 @@ graphql(`
|
|||
}
|
||||
`);
|
||||
|
||||
const { me } = getMe();
|
||||
|
||||
const { result, onResult } = useQuery(
|
||||
graphql(`
|
||||
query AssignmentQuery($id: ID!) {
|
||||
|
|
@ -136,6 +150,35 @@ const { mutate: doUpdateAssignment } = useMutation(
|
|||
}
|
||||
`)
|
||||
);
|
||||
const { mutate: doUpdateAssignmentWithSuccess } = useMutation(
|
||||
graphql(`
|
||||
mutation UpdateAssignmentWithSuccess($input: UpdateAssignmentInput!) {
|
||||
updateAssignment(input: $input) {
|
||||
successful
|
||||
updatedAssignment {
|
||||
...AssignmentParts
|
||||
}
|
||||
}
|
||||
}
|
||||
`)
|
||||
);
|
||||
const { mutate: doSpellCheck } = useMutation(
|
||||
graphql(`
|
||||
mutation SpellCheck($input: SpellCheckInput!) {
|
||||
spellCheck(input: $input) {
|
||||
correct
|
||||
results {
|
||||
sentence
|
||||
offset
|
||||
sentenceOffset
|
||||
length
|
||||
affected
|
||||
corrected
|
||||
}
|
||||
}
|
||||
}
|
||||
`)
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
if (assignmentDiv.value !== null) {
|
||||
|
|
@ -152,6 +195,23 @@ onMounted(() => {
|
|||
}
|
||||
});
|
||||
|
||||
const submission = computed(() => {
|
||||
return assignment.value?.submission || {};
|
||||
});
|
||||
const isStudent = computed(() => {
|
||||
return !me.value.isTeacher;
|
||||
});
|
||||
const solution = computed(() => {
|
||||
return {
|
||||
text: assignment.value.solution,
|
||||
};
|
||||
});
|
||||
const feedbackText = computed(() => {
|
||||
let feedback = assignment.value.submission.submissionFeedback;
|
||||
let sanitizedFeedbackText = sanitize(feedback.text);
|
||||
return `<span class="inline-title">Feedback von ${feedback.teacher.firstName} ${feedback.teacher.lastName}:</span> ${sanitizedFeedbackText}`;
|
||||
});
|
||||
|
||||
const childElements = computed(() => {
|
||||
// todo: refactor and merge with the one in ContentComponent.vue
|
||||
if (assignmentDiv.value) {
|
||||
|
|
@ -264,181 +324,98 @@ const reopen = () => {
|
|||
},
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import { mapActions, mapGetters } from 'vuex';
|
||||
import ASSIGNMENT_QUERY from '@/graphql/gql/queries/assignmentQuery.gql';
|
||||
import ME_QUERY from '@/graphql/gql/queries/meQuery.gql';
|
||||
import UPDATE_ASSIGNMENT_MUTATION_WITH_SUCCESS from '@/graphql/gql/mutations/updateAssignmentMutationWithSuccess.gql';
|
||||
import SPELL_CHECK_MUTATION from '@/graphql/gql/mutations/spellCheck.gql';
|
||||
import debounce from 'lodash/debounce';
|
||||
import { sanitize } from '@/helpers/text';
|
||||
import { defineAsyncComponent } from 'vue';
|
||||
import { matomoTrackEvent } from '@/helpers/matomo-client';
|
||||
import { PAGE_LOAD_TIMEOUT } from '@/consts/navigation.consts';
|
||||
|
||||
const SubmissionForm = defineAsyncComponent(() => import('@/components/content-blocks/assignment/SubmissionForm.vue'));
|
||||
const Solution = defineAsyncComponent(() => import('@/components/content-blocks/Solution.vue'));
|
||||
const SpellCheck = defineAsyncComponent(() => import('@/components/content-blocks/assignment/SpellCheck.vue'));
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Solution,
|
||||
SubmissionForm,
|
||||
SpellCheck,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
me: {
|
||||
permissions: [],
|
||||
const _save = debounce(function (submission) {
|
||||
saving.value++;
|
||||
const variables = {
|
||||
input: {
|
||||
assignment: {
|
||||
id: assignment.value.id,
|
||||
answer: assignment.value.submission.text,
|
||||
document: assignment.value.submission.document,
|
||||
},
|
||||
inputType: 'text',
|
||||
unsaved: false,
|
||||
saving: 0,
|
||||
spellcheckLoading: false,
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapGetters(['scrollToAssignmentId']),
|
||||
final() {
|
||||
return !!this.submission && this.submission.final;
|
||||
},
|
||||
submission() {
|
||||
return this.assignment.submission ? this.assignment.submission : {};
|
||||
},
|
||||
isStudent() {
|
||||
return !this.me.permissions.includes('users.can_manage_school_class_content');
|
||||
},
|
||||
solution() {
|
||||
return {
|
||||
text: this.assignment.solution,
|
||||
};
|
||||
},
|
||||
id() {
|
||||
return this.assignment.id ? this.assignment.id.replace(/=/g, '') : '';
|
||||
},
|
||||
feedbackText() {
|
||||
let feedback = this.assignment.submission.submissionFeedback;
|
||||
let sanitizedFeedbackText = sanitize(feedback.text);
|
||||
return `<span class="inline-title">Feedback von ${feedback.teacher.firstName} ${feedback.teacher.lastName}:</span> ${sanitizedFeedbackText}`;
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
...mapActions(['scrollToAssignmentReady']),
|
||||
_save: debounce(function (submission) {
|
||||
this.saving++;
|
||||
this.$apollo
|
||||
.mutate({
|
||||
mutation: UPDATE_ASSIGNMENT_MUTATION_WITH_SUCCESS,
|
||||
variables: {
|
||||
input: {
|
||||
assignment: {
|
||||
id: this.assignment.id,
|
||||
answer: this.assignment.submission.text,
|
||||
document: this.assignment.submission.document,
|
||||
},
|
||||
};
|
||||
doUpdateAssignmentWithSuccess(variables, {
|
||||
update(
|
||||
cache,
|
||||
{
|
||||
data: {
|
||||
updateAssignment: { successful, updatedAssignment },
|
||||
},
|
||||
}
|
||||
) {
|
||||
try {
|
||||
if (successful) {
|
||||
const id = cache.identify({
|
||||
id: updatedAssignment.id,
|
||||
__typename: updatedAssignment.__typename,
|
||||
});
|
||||
const fragment = assignmentFragment;
|
||||
const fragmentName = 'AssignmentParts';
|
||||
cache.writeFragment({
|
||||
fragment,
|
||||
fragmentName,
|
||||
id,
|
||||
data: {
|
||||
...updatedAssignment,
|
||||
submission,
|
||||
},
|
||||
},
|
||||
update(
|
||||
store,
|
||||
{
|
||||
data: {
|
||||
updateAssignment: { successful, updatedAssignment },
|
||||
},
|
||||
}
|
||||
) {
|
||||
try {
|
||||
if (successful) {
|
||||
const query = ASSIGNMENT_QUERY;
|
||||
const variables = {
|
||||
id: updatedAssignment.id,
|
||||
};
|
||||
const assignment = Object.assign({}, updatedAssignment, {
|
||||
submission,
|
||||
});
|
||||
const data = {
|
||||
assignment,
|
||||
};
|
||||
store.writeQuery({ query, variables, data });
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
// Query did not exist in the cache, and apollo throws a generic Error. Do nothing
|
||||
}
|
||||
},
|
||||
})
|
||||
.then(() => {
|
||||
this.saving--;
|
||||
if (this.saving === 0) {
|
||||
this.unsaved = false;
|
||||
}
|
||||
});
|
||||
}, 500),
|
||||
saveInput: function (answer) {
|
||||
// reset corrections on input
|
||||
this.corrections = '';
|
||||
this.unsaved = true;
|
||||
/*
|
||||
We update the assignment on this component, so the changes are reflected on it. The server does not return
|
||||
the updated entity, to prevent the UI to update when the user is entering his input
|
||||
*/
|
||||
this.assignment.submission.text = answer;
|
||||
this._save(this.assignment.submission);
|
||||
|
||||
if (this.assignment.submission.text.length > 0) {
|
||||
matomoTrackEvent('Auftrag', 'Text mit Eingabe gespeichert', this.assignment.title);
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
// Query did not exist in the cache, and apollo throws a generic Error. Do nothing
|
||||
}
|
||||
},
|
||||
changeDocumentUrl(documentUrl) {
|
||||
this.assignment.submission.document = documentUrl;
|
||||
this._save(this.assignment.submission);
|
||||
},
|
||||
initialSubmission() {
|
||||
return {
|
||||
text: '',
|
||||
document: '',
|
||||
final: false,
|
||||
};
|
||||
},
|
||||
spellcheck() {
|
||||
let self = this;
|
||||
this.spellcheckLoading = true;
|
||||
this.$apollo
|
||||
.mutate({
|
||||
mutation: SPELL_CHECK_MUTATION,
|
||||
variables: {
|
||||
input: {
|
||||
assignment: this.assignment.id,
|
||||
text: this.assignment.submission.text,
|
||||
},
|
||||
},
|
||||
update(
|
||||
store,
|
||||
{
|
||||
data: {
|
||||
spellCheck: { results },
|
||||
},
|
||||
}
|
||||
) {
|
||||
self.corrections = results;
|
||||
},
|
||||
})
|
||||
.then(() => {
|
||||
this.spellcheckLoading = false;
|
||||
});
|
||||
matomoTrackEvent('Auftrag', 'Rechtschreibung geprüft', this.assignment.title);
|
||||
},
|
||||
},
|
||||
}).then(() => {
|
||||
saving.value--;
|
||||
if (saving.value === 0) {
|
||||
unsaved.value = false;
|
||||
}
|
||||
});
|
||||
}, 500);
|
||||
const saveInput = (answer: string) => {
|
||||
// reset corrections on input
|
||||
corrections.value = '';
|
||||
unsaved.value = true;
|
||||
/*
|
||||
We update the assignment on this component, so the changes are reflected on it. The server does not return
|
||||
the updated entity, to prevent the UI to update when the user is entering his input
|
||||
*/
|
||||
assignment.value.submission.text = answer;
|
||||
_save(assignment.value.submission);
|
||||
|
||||
apollo: {
|
||||
me: {
|
||||
query: ME_QUERY,
|
||||
if (assignment.value.submission.text.length > 0) {
|
||||
matomoTrackEvent('Auftrag', 'Text mit Eingabe gespeichert', assignment.value.title);
|
||||
}
|
||||
};
|
||||
const changeDocumentUrl = (documentUrl: string) => {
|
||||
assignment.value.submission.document = documentUrl;
|
||||
_save(assignment.value.submission);
|
||||
};
|
||||
const spellcheck = () => {
|
||||
spellcheckLoading.value = true;
|
||||
const variables = {
|
||||
input: {
|
||||
assignment: assignment.value.id,
|
||||
text: assignment.value.submission.text,
|
||||
},
|
||||
},
|
||||
};
|
||||
doSpellCheck(variables, {
|
||||
update(
|
||||
_cache,
|
||||
{
|
||||
data: {
|
||||
spellCheck: { results },
|
||||
},
|
||||
}
|
||||
) {
|
||||
corrections.value = results;
|
||||
},
|
||||
}).then(() => {
|
||||
spellcheckLoading.value = false;
|
||||
});
|
||||
matomoTrackEvent('Auftrag', 'Rechtschreibung geprüft', assignment.value.title);
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ export default {
|
|||
slug,
|
||||
});
|
||||
const fragment = MODULE_FRAGMENT;
|
||||
const fragmentName = 'ModuleParts';
|
||||
const fragmentName = 'ModuleLegacyParts';
|
||||
const module = store.readFragment({ fragment, fragmentName, id });
|
||||
const data = {
|
||||
...module,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#import "./highlightParts.gql"
|
||||
fragment ModuleParts on ModuleNode {
|
||||
fragment ModuleLegacyParts on ModuleNode {
|
||||
id
|
||||
title
|
||||
metaTitle
|
||||
|
|
|
|||
|
|
@ -8,6 +8,6 @@ fragment RoomParts on RoomNode {
|
|||
description
|
||||
restricted
|
||||
schoolClass {
|
||||
...SchoolClassParts
|
||||
...SchoolClassLegacyParts
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
fragment SchoolClassParts on SchoolClassNode {
|
||||
fragment SchoolClassLegacyParts on SchoolClassNode {
|
||||
id
|
||||
name
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
fragment TeamParts on TeamNode {
|
||||
fragment TeamLegacyParts on TeamNode {
|
||||
name
|
||||
code
|
||||
id
|
||||
|
|
|
|||
|
|
@ -8,6 +8,6 @@ fragment TopicParts on TopicNode {
|
|||
vimeoId
|
||||
instructions
|
||||
modules {
|
||||
...ModuleParts
|
||||
...ModuleLegacyParts
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#import "./schoolClassParts.gql"
|
||||
#import "./moduleParts.gql"
|
||||
fragment UserParts on PrivateUserNode {
|
||||
fragment UserLegacyParts on PrivateUserNode {
|
||||
id
|
||||
pk
|
||||
username
|
||||
|
|
@ -30,11 +30,11 @@ fragment UserParts on PrivateUserNode {
|
|||
recentModules(orderBy: "-visited") {
|
||||
edges {
|
||||
node {
|
||||
...ModuleParts
|
||||
...ModuleLegacyParts
|
||||
}
|
||||
}
|
||||
}
|
||||
schoolClasses {
|
||||
...SchoolClassParts
|
||||
...SchoolClassLegacyParts
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ mutation CreateTeamMutation($input: CreateTeamInput!) {
|
|||
result {
|
||||
__typename
|
||||
... on TeamNode {
|
||||
...TeamParts
|
||||
...TeamLegacyParts
|
||||
}
|
||||
... on DuplicateName {
|
||||
reason
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ mutation JoinTeamMutation($input: JoinTeamInput!) {
|
|||
joinTeam(input: $input) {
|
||||
success
|
||||
team {
|
||||
...TeamParts
|
||||
...TeamLegacyParts
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ mutation ApplySnapshot($input: ApplySnapshotInput!) {
|
|||
applySnapshot(input: $input) {
|
||||
success
|
||||
module {
|
||||
...ModuleParts
|
||||
...ModuleLegacyParts
|
||||
objectiveGroups {
|
||||
...ObjectiveGroupParts
|
||||
objectives {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
mutation UpdateLastModule($input: UpdateLastModuleInput!) {
|
||||
updateLastModule(input: $input) {
|
||||
lastModule {
|
||||
...ModuleParts
|
||||
...ModuleLegacyParts
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ query ModulesQuery {
|
|||
modules {
|
||||
edges {
|
||||
node {
|
||||
...ModuleParts
|
||||
...ModuleLegacyParts
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ query AssignmentWithSubmissions($id: ID!) {
|
|||
firstName
|
||||
lastName
|
||||
schoolClasses {
|
||||
...SchoolClassParts
|
||||
...SchoolClassLegacyParts
|
||||
}
|
||||
}
|
||||
submissionFeedback {
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@
|
|||
#import "../fragments/teamParts.gql"
|
||||
query MeQuery {
|
||||
me {
|
||||
...UserParts
|
||||
...UserLegacyParts
|
||||
team {
|
||||
...TeamParts
|
||||
...TeamLegacyParts
|
||||
}
|
||||
isTeacher
|
||||
permissions
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#import "../fragments/moduleParts.gql"
|
||||
query ModuleQuery($id: ID, $slug: String) {
|
||||
module(id: $id, slug: $slug) {
|
||||
...ModuleParts
|
||||
...ModuleLegacyParts
|
||||
chapters {
|
||||
id
|
||||
contentBlocks {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
#import "gql/fragments/contentBlockParts.gql"
|
||||
query ModuleDetailsQuery($slug: String, $id: ID) {
|
||||
module(slug: $slug, id: $id) {
|
||||
...ModuleParts
|
||||
...ModuleLegacyParts
|
||||
objectiveGroups {
|
||||
...ObjectiveGroupParts
|
||||
objectives {
|
||||
|
|
|
|||
|
|
@ -31,4 +31,120 @@ export function meQuery() {
|
|||
};
|
||||
}
|
||||
|
||||
export { getModule };
|
||||
graphql(`
|
||||
fragment SchoolClassParts on SchoolClassNode {
|
||||
id
|
||||
name
|
||||
}
|
||||
`);
|
||||
graphql(`
|
||||
fragment UserParts on PrivateUserNode {
|
||||
id
|
||||
pk
|
||||
username
|
||||
email
|
||||
firstName
|
||||
lastName
|
||||
avatarUrl
|
||||
expiryDate
|
||||
readOnly
|
||||
lastModuleLevel {
|
||||
id
|
||||
name
|
||||
filterAttributeType
|
||||
}
|
||||
lastModule {
|
||||
id
|
||||
slug
|
||||
}
|
||||
lastTopic {
|
||||
id
|
||||
slug
|
||||
}
|
||||
selectedClass {
|
||||
id
|
||||
readOnly
|
||||
}
|
||||
recentModules(orderBy: "-visited") {
|
||||
edges {
|
||||
node {
|
||||
...ModuleParts
|
||||
}
|
||||
}
|
||||
}
|
||||
schoolClasses {
|
||||
...SchoolClassParts
|
||||
}
|
||||
}
|
||||
`);
|
||||
graphql(`
|
||||
fragment TeamParts on TeamNode {
|
||||
name
|
||||
code
|
||||
id
|
||||
members {
|
||||
firstName
|
||||
lastName
|
||||
id
|
||||
isMe
|
||||
}
|
||||
}
|
||||
`);
|
||||
graphql(`
|
||||
fragment ModuleParts on ModuleNode {
|
||||
id
|
||||
title
|
||||
metaTitle
|
||||
teaser
|
||||
intro
|
||||
slug
|
||||
heroImage
|
||||
heroSource
|
||||
solutionsEnabled
|
||||
highlights {
|
||||
...HighlightParts
|
||||
}
|
||||
language
|
||||
inEditMode @client
|
||||
level {
|
||||
id
|
||||
name
|
||||
}
|
||||
category {
|
||||
id
|
||||
name
|
||||
}
|
||||
topic {
|
||||
slug
|
||||
title
|
||||
}
|
||||
bookmark {
|
||||
note {
|
||||
id
|
||||
text
|
||||
}
|
||||
}
|
||||
}
|
||||
`);
|
||||
|
||||
const getMe = () => {
|
||||
const query = graphql(`
|
||||
query MeQuery {
|
||||
me {
|
||||
...UserParts
|
||||
team {
|
||||
...TeamParts
|
||||
}
|
||||
isTeacher
|
||||
permissions
|
||||
onboardingVisited
|
||||
}
|
||||
}
|
||||
`);
|
||||
const { result } = useQuery(query);
|
||||
const me = computed(() => result.value?.me || { isTeacher: false });
|
||||
|
||||
return { me };
|
||||
};
|
||||
|
||||
export { getModule, getMe };
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ export const constructNoteMutation = (n) => {
|
|||
});
|
||||
} else {
|
||||
let fragment = MODULE_FRAGMENT;
|
||||
const fragmentName = 'ModuleParts';
|
||||
const fragmentName = 'ModuleLegacyParts';
|
||||
let id = store.identify({
|
||||
__typename: 'ModuleNode',
|
||||
slug: n.parent,
|
||||
|
|
|
|||
|
|
@ -163,7 +163,7 @@ export default {
|
|||
slug: slug,
|
||||
});
|
||||
|
||||
const fragmentName = 'ModuleParts';
|
||||
const fragmentName = 'ModuleLegacyParts';
|
||||
const module = store.readFragment({
|
||||
fragment,
|
||||
id,
|
||||
|
|
|
|||
Loading…
Reference in New Issue