diff --git a/.editorconfig b/.editorconfig index 24367a8d..561c6e93 100644 --- a/.editorconfig +++ b/.editorconfig @@ -12,7 +12,7 @@ trim_trailing_whitespace = true indent_style = space indent_size = 4 -[*.{html,css,scss,json,yml,js,vue,ts,md,xml}] +[*.{html,css,scss,json,yml,js,vue,ts,md,xml,gql}] indent_style = space indent_size = 2 diff --git a/README.md b/README.md index e4c4b18d..1f68435f 100644 --- a/README.md +++ b/README.md @@ -209,3 +209,28 @@ There are some rules when it comes to the folder structure of the frontend.    ├─ AbcButton.vue    └─ AbcListTile.vue ``` + +## GraphQL + +When you change something on the server side run the following command to update the +graphql schema: + +```bash +python manage.py graphql_schema +``` + +On the client side you can (or even have to) run the following command to update the +generated code + +```bash +npm run codegen + +# or in watch mode +npm run codegen:watch +``` + +### Open Questions + +- The `id` field has to be a string? +- Is running `codegen` a prerequisite so that it even works? +- The functions is `cacheExchange` should be nearer the concrete implementation \ No newline at end of file diff --git a/client/.eslintrc.cjs b/client/.eslintrc.cjs index ccfed85b..a73671ae 100644 --- a/client/.eslintrc.cjs +++ b/client/.eslintrc.cjs @@ -15,7 +15,14 @@ module.exports = { env: { "vue/setup-compiler-macros": true, }, - ignorePatterns: ["versionize.js", "tailwind.config.js", "postcss.config.js"], + ignorePatterns: [ + "versionize.js", + "tailwind.config.js", + "postcss.config.js", + "src/gql/**/*.ts", + "src/stories/**/*", + "src/**/*.stories.ts", + ], rules: { "@typescript-eslint/ban-ts-comment": "warn", "@typescript-eslint/no-explicit-any": "warn", diff --git a/client/.prettierignore b/client/.prettierignore index 80cb10cb..bb7923a3 100644 --- a/client/.prettierignore +++ b/client/.prettierignore @@ -2,3 +2,4 @@ dist node_modules **/__tests__/*.json src/colors.json +src/gql/* \ No newline at end of file diff --git a/client/codegen.ts b/client/codegen.ts index 36c05d42..5d95944d 100644 --- a/client/codegen.ts +++ b/client/codegen.ts @@ -1,7 +1,8 @@ import type { CodegenConfig } from "@graphql-codegen/cli"; + const config: CodegenConfig = { schema: "../server/schema.graphql", - documents: ["src/**/*.vue"], + documents: ["src/**/*.vue", "src/graphql/**/*.ts"], ignoreNoDocuments: true, generates: { "./src/gql/": { diff --git a/client/package-lock.json b/client/package-lock.json index 62b5c873..43dd9f8d 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -12,7 +12,9 @@ "@headlessui/vue": "1.7.7", "@sentry/tracing": "^7.20.0", "@sentry/vue": "^7.20.0", - "@urql/vue": "^1.0.2", + "@urql/devtools": "^2.0.3", + "@urql/exchange-graphcache": "^6.0.4", + "@urql/vue": "^1.1.1", "@vueuse/core": "^9.13.0", "@vueuse/router": "^10.1.2", "cypress": "^12.9.0", @@ -89,6 +91,19 @@ "vue-tsc": "^1.0.9" } }, + "node_modules/@0no-co/graphql.web": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@0no-co/graphql.web/-/graphql.web-1.0.1.tgz", + "integrity": "sha512-6Yaxyv6rOwRkLIvFaL0NrLDgfNqC/Ng9QOPmTmlqW4mORXMEKmh5NYGkIvvt5Yw8fZesnMAqkj8cIqTj8f40cQ==", + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0" + }, + "peerDependenciesMeta": { + "graphql": { + "optional": true + } + } + }, "node_modules/@ampproject/remapping": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", @@ -6996,26 +7011,45 @@ } }, "node_modules/@urql/core": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/@urql/core/-/core-3.2.2.tgz", - "integrity": "sha512-i046Cz8cZ4xIzGMTyHZrbdgzcFMcKD7+yhCAH5FwWBRjcKrc+RjEOuR9X5AMuBvr8c6IAaE92xAqa4wmlGfWTQ==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@urql/core/-/core-4.0.7.tgz", + "integrity": "sha512-UtZ9oSbSFODXzFydgLCXpAQz26KGT1d6uEfcylKphiRWNXSWZi8k7vhJXNceNm/Dn0MiZ+kaaJHKcnGY1jvHRQ==", "dependencies": { - "wonka": "^6.1.2" + "@0no-co/graphql.web": "^1.0.1", + "wonka": "^6.3.2" + } + }, + "node_modules/@urql/devtools": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@urql/devtools/-/devtools-2.0.3.tgz", + "integrity": "sha512-TktPLiBS9LcBPHD6qcnb8wqOVcg3Bx0iCtvQ80uPpfofwwBGJmqnQTjUdEFU6kwaLOFZULQ9+Uo4831G823mQw==", + "dependencies": { + "wonka": ">= 4.0.9" }, "peerDependencies": { - "graphql": "^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" + "@urql/core": ">= 1.14.0", + "graphql": ">= 0.11.0" + } + }, + "node_modules/@urql/exchange-graphcache": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@urql/exchange-graphcache/-/exchange-graphcache-6.0.4.tgz", + "integrity": "sha512-fzfCUrHzhLycPRa6kYrQYryk0pwmUfeHY9Xqh11A6wtp4/diV7FASlffB5k2j3AWRBxBnqThXDssRXI/G8cACQ==", + "dependencies": { + "@0no-co/graphql.web": "^1.0.1", + "@urql/core": ">=4.0.0", + "wonka": "^6.3.2" } }, "node_modules/@urql/vue": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@urql/vue/-/vue-1.0.5.tgz", - "integrity": "sha512-RiXiINAr/tBJTIRcbA+TPCwRvK/z3NJy7+NOQvXHV/c9nCDrmUgu7HqdVMtAmlh5jUIw3HR8nI8IrRUoJqchHw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@urql/vue/-/vue-1.1.1.tgz", + "integrity": "sha512-dFHyJdqcTbr5P5nLfagh7CYDuuy91S7T0oaWZRJJDpq+53uTAjaRk7XQ8UNQH2oaZTO5djhQRruaPOY2JbjJsg==", "dependencies": { - "@urql/core": "^3.2.0", - "wonka": "^6.0.0" + "@urql/core": "^4.0.0", + "wonka": "^6.3.2" }, "peerDependencies": { - "graphql": "^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0", "vue": "^2.7.0 || ^3.0.0" } }, @@ -19554,9 +19588,9 @@ } }, "node_modules/wonka": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/wonka/-/wonka-6.3.1.tgz", - "integrity": "sha512-nJyGPcjuBiaLFn8QAlrHd+QjV9AlPO7snOWAhgx6aX0nQLMV6Wi0nqfrkmsXIH0efngbDOroOz2QyLnZMF16Hw==" + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/wonka/-/wonka-6.3.2.tgz", + "integrity": "sha512-2xXbQ1LnwNS7egVm1HPhW2FyKrekolzhpM3mCwXdQr55gO+tAiY76rhb32OL9kKsW8taj++iP7C6hxlVzbnvrw==" }, "node_modules/word-wrap": { "version": "1.2.3", @@ -19741,6 +19775,11 @@ } }, "dependencies": { + "@0no-co/graphql.web": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@0no-co/graphql.web/-/graphql.web-1.0.1.tgz", + "integrity": "sha512-6Yaxyv6rOwRkLIvFaL0NrLDgfNqC/Ng9QOPmTmlqW4mORXMEKmh5NYGkIvvt5Yw8fZesnMAqkj8cIqTj8f40cQ==" + }, "@ampproject/remapping": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", @@ -24929,20 +24968,39 @@ } }, "@urql/core": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/@urql/core/-/core-3.2.2.tgz", - "integrity": "sha512-i046Cz8cZ4xIzGMTyHZrbdgzcFMcKD7+yhCAH5FwWBRjcKrc+RjEOuR9X5AMuBvr8c6IAaE92xAqa4wmlGfWTQ==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@urql/core/-/core-4.0.7.tgz", + "integrity": "sha512-UtZ9oSbSFODXzFydgLCXpAQz26KGT1d6uEfcylKphiRWNXSWZi8k7vhJXNceNm/Dn0MiZ+kaaJHKcnGY1jvHRQ==", "requires": { - "wonka": "^6.1.2" + "@0no-co/graphql.web": "^1.0.1", + "wonka": "^6.3.2" + } + }, + "@urql/devtools": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@urql/devtools/-/devtools-2.0.3.tgz", + "integrity": "sha512-TktPLiBS9LcBPHD6qcnb8wqOVcg3Bx0iCtvQ80uPpfofwwBGJmqnQTjUdEFU6kwaLOFZULQ9+Uo4831G823mQw==", + "requires": { + "wonka": ">= 4.0.9" + } + }, + "@urql/exchange-graphcache": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@urql/exchange-graphcache/-/exchange-graphcache-6.0.4.tgz", + "integrity": "sha512-fzfCUrHzhLycPRa6kYrQYryk0pwmUfeHY9Xqh11A6wtp4/diV7FASlffB5k2j3AWRBxBnqThXDssRXI/G8cACQ==", + "requires": { + "@0no-co/graphql.web": "^1.0.1", + "@urql/core": ">=4.0.0", + "wonka": "^6.3.2" } }, "@urql/vue": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@urql/vue/-/vue-1.0.5.tgz", - "integrity": "sha512-RiXiINAr/tBJTIRcbA+TPCwRvK/z3NJy7+NOQvXHV/c9nCDrmUgu7HqdVMtAmlh5jUIw3HR8nI8IrRUoJqchHw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@urql/vue/-/vue-1.1.1.tgz", + "integrity": "sha512-dFHyJdqcTbr5P5nLfagh7CYDuuy91S7T0oaWZRJJDpq+53uTAjaRk7XQ8UNQH2oaZTO5djhQRruaPOY2JbjJsg==", "requires": { - "@urql/core": "^3.2.0", - "wonka": "^6.0.0" + "@urql/core": "^4.0.0", + "wonka": "^6.3.2" } }, "@vitejs/plugin-vue": { @@ -34332,9 +34390,9 @@ } }, "wonka": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/wonka/-/wonka-6.3.1.tgz", - "integrity": "sha512-nJyGPcjuBiaLFn8QAlrHd+QjV9AlPO7snOWAhgx6aX0nQLMV6Wi0nqfrkmsXIH0efngbDOroOz2QyLnZMF16Hw==" + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/wonka/-/wonka-6.3.2.tgz", + "integrity": "sha512-2xXbQ1LnwNS7egVm1HPhW2FyKrekolzhpM3mCwXdQr55gO+tAiY76rhb32OL9kKsW8taj++iP7C6hxlVzbnvrw==" }, "word-wrap": { "version": "1.2.3", diff --git a/client/package.json b/client/package.json index 22b01fd1..e3f60e3c 100644 --- a/client/package.json +++ b/client/package.json @@ -2,28 +2,31 @@ "name": "client", "version": "0.0.0", "scripts": { - "dev": "vite", "build": "vue-tsc --noEmit && vite build && node versionize && cp ./dist/index.html ../server/vbv_lernwelt/templates/vue/index.html && rm -rf ../server/vbv_lernwelt/static/vue/* && cp -r ./dist/static/vue ../server/vbv_lernwelt/static/ && npm run build-storybook", + "build-storybook": "rm -rf ../server/vbv_lernwelt/static/storybook/* && storybook build -o ../server/vbv_lernwelt/static/storybook", "build:tailwind": "tailwindcss -i tailwind.css -o ../server/vbv_lernwelt/static/css/tailwind.css --minify", "codegen": "graphql-codegen", - "test": "vitest run", + "codegen:watch": "graphql-codegen --watch", "coverage": "vitest run --coverage", - "typecheck": "vue-tsc --noEmit -p tsconfig.app.json --composite false", + "cypress:open": "cypress open", + "dev": "vite", "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore", - "vue-i18n-extract": "vue-i18n-extract report", "prettier": "prettier . --write", "prettier:check": "prettier . --check", - "tailwind": "tailwindcss -i tailwind.css -o ../server/vbv_lernwelt/static/css/tailwind.css --watch", "storybook": "storybook dev -p 6006", - "build-storybook": "rm -rf ../server/vbv_lernwelt/static/storybook/* && storybook build -o ../server/vbv_lernwelt/static/storybook", - "cypress:open": "cypress open" + "tailwind": "tailwindcss -i tailwind.css -o ../server/vbv_lernwelt/static/css/tailwind.css --watch", + "test": "vitest run", + "typecheck": "vue-tsc --noEmit -p tsconfig.app.json --composite false", + "vue-i18n-extract": "vue-i18n-extract report" }, "dependencies": { "@headlessui/tailwindcss": "^0.1.2", "@headlessui/vue": "1.7.7", "@sentry/tracing": "^7.20.0", "@sentry/vue": "^7.20.0", - "@urql/vue": "^1.0.2", + "@urql/devtools": "^2.0.3", + "@urql/exchange-graphcache": "^6.0.4", + "@urql/vue": "^1.1.1", "@vueuse/core": "^9.13.0", "@vueuse/router": "^10.1.2", "cypress": "^12.9.0", diff --git a/client/src/App.vue b/client/src/App.vue index a0885600..ad7b919b 100644 --- a/client/src/App.vue +++ b/client/src/App.vue @@ -15,13 +15,17 @@ import log from "loglevel"; import AppFooter from "@/components/AppFooter.vue"; import MainNavigationBar from "@/components/header/MainNavigationBar.vue"; +import { graphqlClient } from "@/graphql/client"; import eventBus from "@/utils/eventBus"; +import { provideClient } from "@urql/vue"; import { onMounted, ref } from "vue"; const componentKey = ref(1); log.debug("App created"); +provideClient(graphqlClient); + onMounted(() => { log.debug("App mounted"); diff --git a/client/src/components/FeedbackForm.vue b/client/src/components/FeedbackForm.vue index 2673badd..2b02e830 100644 --- a/client/src/components/FeedbackForm.vue +++ b/client/src/components/FeedbackForm.vue @@ -53,8 +53,8 @@ const numSteps = stepLabels.length; const sendFeedbackMutation = graphql(` mutation SendFeedbackMutation($input: SendFeedbackInput!) { - sendFeedback(input: $input) { - feedbackResponse { + send_feedback(input: $input) { + feedback_response { id } errors { @@ -112,7 +112,7 @@ const sendFeedback = () => { would_recommend: wouldRecommend, }, page: props.page.translation_key, - courseSession: courseSession.id, + course_session: courseSession.id, }); const variables = reactive({ input, diff --git a/server/vbv_lernwelt/utils/__init__.py b/client/src/composables.ts similarity index 100% rename from server/vbv_lernwelt/utils/__init__.py rename to client/src/composables.ts diff --git a/client/src/gql/fragment-masking.ts b/client/src/gql/fragment-masking.ts index 562afc32..a94b5c77 100644 --- a/client/src/gql/fragment-masking.ts +++ b/client/src/gql/fragment-masking.ts @@ -1,13 +1,16 @@ -import type { TypedDocumentNode as DocumentNode } from "@graphql-typed-document-node/core"; +import type { ResultOf, TypedDocumentNode as DocumentNode, } from '@graphql-typed-document-node/core'; -export type FragmentType> = - TDocumentType extends DocumentNode - ? TType extends { " $fragmentName"?: infer TKey } - ? TKey extends string - ? { " $fragmentRefs"?: { [key in TKey]: TType } } - : never + +export type FragmentType> = TDocumentType extends DocumentNode< + infer TType, + any +> + ? TType extends { ' $fragmentName'?: infer TKey } + ? TKey extends string + ? { ' $fragmentRefs'?: { [key in TKey]: TType } } : never - : never; + : never + : never; // return non-nullable if `fragmentType` is non-nullable export function useFragment( @@ -31,11 +34,15 @@ export function useFragment( ): ReadonlyArray | null | undefined; export function useFragment( _documentNode: DocumentNode, - fragmentType: - | FragmentType> - | ReadonlyArray>> - | null - | undefined + fragmentType: FragmentType> | ReadonlyArray>> | null | undefined ): TType | ReadonlyArray | null | undefined { return fragmentType as any; } + + +export function makeFragmentData< + F extends DocumentNode, + FT extends ResultOf +>(data: FT, _fragment: F): FragmentType { + return data as FragmentType; +} \ No newline at end of file diff --git a/client/src/gql/gql.ts b/client/src/gql/gql.ts index 836d3f18..445ec901 100644 --- a/client/src/gql/gql.ts +++ b/client/src/gql/gql.ts @@ -1,20 +1,57 @@ /* eslint-disable */ -import type { TypedDocumentNode as DocumentNode } from "@graphql-typed-document-node/core"; -import * as types from "./graphql"; +import * as types from './graphql'; +import type { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; +/** + * Map of all GraphQL operations in the project. + * + * This map has several performance disadvantages: + * 1. It is not tree-shakeable, so it will include all operations in the project. + * 2. It is not minifiable, so the string of a GraphQL query will be multiple times inside the bundle. + * 3. It does not support dead code elimination, so it will add unused operations. + * + * Therefore it is highly recommended to use the babel-plugin for production. + */ const documents = { - "\n mutation SendFeedbackMutation($input: SendFeedbackInput!) {\n sendFeedback(input: $input) {\n feedbackResponse {\n id\n }\n errors {\n field\n messages\n }\n }\n }\n": - types.SendFeedbackMutationDocument, + "\n mutation SendFeedbackMutation($input: SendFeedbackInput!) {\n send_feedback(input: $input) {\n feedback_response {\n id\n }\n errors {\n field\n messages\n }\n }\n }\n": types.SendFeedbackMutationDocument, + "\n mutation UpsertAssignmentCompletion(\n $assignmentId: ID!\n $courseSessionId: ID!\n $assignmentUserId: ID\n $completionStatus: String!\n $completionDataString: String!\n $evaluationGrade: Float\n $evaluationPoints: Float\n ) {\n upsert_assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n assignment_user_id: $assignmentUserId\n completion_status: $completionStatus\n completion_data_string: $completionDataString\n evaluation_grade: $evaluationGrade\n evaluation_points: $evaluationPoints\n ) {\n assignment_completion {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_grade\n evaluation_points\n completion_data\n }\n }\n }\n": types.UpsertAssignmentCompletionDocument, + "\n query assignmentCompletionQuery(\n $assignmentId: ID!\n $courseSessionId: ID!\n $assignmentUserId: ID\n ) {\n assignment(id: $assignmentId) {\n id\n content_type\n evaluation_description\n evaluation_document_url\n evaluation_tasks\n performance_objectives\n starting_position\n tasks\n title\n translation_key\n slug\n }\n assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n assignment_user_id: $assignmentUserId\n ) {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_user {\n id\n }\n assignment_user {\n id\n }\n evaluation_grade\n evaluation_points\n completion_data\n }\n }\n": types.AssignmentCompletionQueryDocument, + "\n query courseQuery($courseId: Int!) {\n course(id: $courseId) {\n id\n slug\n title\n category_name\n learning_path {\n id\n }\n }\n }\n": types.CourseQueryDocument, }; -export function graphql( - source: "\n mutation SendFeedbackMutation($input: SendFeedbackInput!) {\n sendFeedback(input: $input) {\n feedbackResponse {\n id\n }\n errors {\n field\n messages\n }\n }\n }\n" -): (typeof documents)["\n mutation SendFeedbackMutation($input: SendFeedbackInput!) {\n sendFeedback(input: $input) {\n feedbackResponse {\n id\n }\n errors {\n field\n messages\n }\n }\n }\n"]; - +/** + * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. + * + * + * @example + * ```ts + * const query = gql(`query GetUser($id: ID!) { user(id: $id) { name } }`); + * ``` + * + * The query argument is unknown! + * Please regenerate the types. + */ 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 mutation SendFeedbackMutation($input: SendFeedbackInput!) {\n send_feedback(input: $input) {\n feedback_response {\n id\n }\n errors {\n field\n messages\n }\n }\n }\n"): (typeof documents)["\n mutation SendFeedbackMutation($input: SendFeedbackInput!) {\n send_feedback(input: $input) {\n feedback_response {\n id\n }\n errors {\n field\n messages\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 UpsertAssignmentCompletion(\n $assignmentId: ID!\n $courseSessionId: ID!\n $assignmentUserId: ID\n $completionStatus: String!\n $completionDataString: String!\n $evaluationGrade: Float\n $evaluationPoints: Float\n ) {\n upsert_assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n assignment_user_id: $assignmentUserId\n completion_status: $completionStatus\n completion_data_string: $completionDataString\n evaluation_grade: $evaluationGrade\n evaluation_points: $evaluationPoints\n ) {\n assignment_completion {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_grade\n evaluation_points\n completion_data\n }\n }\n }\n"): (typeof documents)["\n mutation UpsertAssignmentCompletion(\n $assignmentId: ID!\n $courseSessionId: ID!\n $assignmentUserId: ID\n $completionStatus: String!\n $completionDataString: String!\n $evaluationGrade: Float\n $evaluationPoints: Float\n ) {\n upsert_assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n assignment_user_id: $assignmentUserId\n completion_status: $completionStatus\n completion_data_string: $completionDataString\n evaluation_grade: $evaluationGrade\n evaluation_points: $evaluationPoints\n ) {\n assignment_completion {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_grade\n evaluation_points\n completion_data\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 assignmentCompletionQuery(\n $assignmentId: ID!\n $courseSessionId: ID!\n $assignmentUserId: ID\n ) {\n assignment(id: $assignmentId) {\n id\n content_type\n evaluation_description\n evaluation_document_url\n evaluation_tasks\n performance_objectives\n starting_position\n tasks\n title\n translation_key\n slug\n }\n assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n assignment_user_id: $assignmentUserId\n ) {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_user {\n id\n }\n assignment_user {\n id\n }\n evaluation_grade\n evaluation_points\n completion_data\n }\n }\n"): (typeof documents)["\n query assignmentCompletionQuery(\n $assignmentId: ID!\n $courseSessionId: ID!\n $assignmentUserId: ID\n ) {\n assignment(id: $assignmentId) {\n id\n content_type\n evaluation_description\n evaluation_document_url\n evaluation_tasks\n performance_objectives\n starting_position\n tasks\n title\n translation_key\n slug\n }\n assignment_completion(\n assignment_id: $assignmentId\n course_session_id: $courseSessionId\n assignment_user_id: $assignmentUserId\n ) {\n id\n completion_status\n submitted_at\n evaluation_submitted_at\n evaluation_user {\n id\n }\n assignment_user {\n id\n }\n evaluation_grade\n evaluation_points\n completion_data\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 courseQuery($courseId: Int!) {\n course(id: $courseId) {\n id\n slug\n title\n category_name\n learning_path {\n id\n }\n }\n }\n"): (typeof documents)["\n query courseQuery($courseId: Int!) {\n course(id: $courseId) {\n id\n slug\n title\n category_name\n learning_path {\n id\n }\n }\n }\n"]; + export function graphql(source: string) { return (documents as any)[source] ?? {}; } -export type DocumentType> = - TDocumentNode extends DocumentNode ? TType : never; +export type DocumentType> = TDocumentNode extends DocumentNode< infer TType, any> ? TType : never; \ No newline at end of file diff --git a/client/src/gql/graphql.ts b/client/src/gql/graphql.ts index 6295ed2b..c717f19c 100644 --- a/client/src/gql/graphql.ts +++ b/client/src/gql/graphql.ts @@ -1,14 +1,10 @@ /* eslint-disable */ -import type { TypedDocumentNode as DocumentNode } from "@graphql-typed-document-node/core"; +import type { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; export type Maybe = T | null; export type InputMaybe = Maybe; export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { - [SubKey in K]?: Maybe; -}; -export type MakeMaybe = Omit & { - [SubKey in K]: Maybe; -}; +export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; +export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; /** All built-in and custom scalars, mapped to their actual values */ export type Scalars = { ID: string; @@ -16,1913 +12,278 @@ export type Scalars = { Boolean: boolean; Int: number; Float: number; + /** + * The `DateTime` scalar type represents a DateTime + * value as specified by + * [iso8601](https://en.wikipedia.org/wiki/ISO_8601). + */ DateTime: any; + /** + * The `GenericScalar` scalar type represents a generic + * GraphQL scalar value that could be: + * String, Boolean, Int, Float, List or Object. + */ GenericScalar: any; + JSONStreamField: any; + /** + * Allows use of a JSON String for input / output from the GraphQL schema. + * + * Use of this type is *not recommended* as you lose the benefits of having a defined, static + * schema (one of the key benefits of GraphQL). + */ JSONString: any; - PositiveInt: any; - UUID: any; }; -export type BlockQuoteBlock = StreamFieldInterface & { - __typename?: "BlockQuoteBlock"; - blockType: Scalars["String"]; - field: Scalars["String"]; - id?: Maybe; - rawValue: Scalars["String"]; - value: Scalars["String"]; +/** An enumeration. */ +export enum AssignmentAssignmentCompletionCompletionStatusChoices { + /** EVALUATION_IN_PROGRESS */ + EvaluationInProgress = 'EVALUATION_IN_PROGRESS', + /** EVALUATION_SUBMITTED */ + EvaluationSubmitted = 'EVALUATION_SUBMITTED', + /** IN_PROGRESS */ + InProgress = 'IN_PROGRESS', + /** SUBMITTED */ + Submitted = 'SUBMITTED' +} + +export type AssignmentCompletionMutation = { + __typename?: 'AssignmentCompletionMutation'; + assignment_completion?: Maybe; }; -export type BooleanBlock = StreamFieldInterface & { - __typename?: "BooleanBlock"; - blockType: Scalars["String"]; - field: Scalars["String"]; - id?: Maybe; - rawValue: Scalars["String"]; - value: Scalars["Boolean"]; +export type AssignmentCompletionType = { + __typename?: 'AssignmentCompletionType'; + additional_json_data: Scalars['JSONString']; + assignment: AssignmentType; + assignment_user: UserType; + completion_data?: Maybe; + completion_status: AssignmentAssignmentCompletionCompletionStatusChoices; + created_at: Scalars['DateTime']; + evaluation_grade?: Maybe; + evaluation_points?: Maybe; + evaluation_submitted_at?: Maybe; + evaluation_user?: Maybe; + id: Scalars['ID']; + submitted_at?: Maybe; + updated_at: Scalars['DateTime']; }; -export type CharBlock = StreamFieldInterface & { - __typename?: "CharBlock"; - blockType: Scalars["String"]; - field: Scalars["String"]; - id?: Maybe; - rawValue: Scalars["String"]; - value: Scalars["String"]; +export type AssignmentType = CoursePageInterface & { + __typename?: 'AssignmentType'; + content_type?: Maybe; + /** Zeitaufwand als Text */ + effort_required: Scalars['String']; + /** Beschreibung der Bewertung */ + evaluation_description: Scalars['String']; + /** URL zum Beurteilungsinstrument */ + evaluation_document_url: Scalars['String']; + evaluation_tasks?: Maybe; + frontend_url?: Maybe; + id?: Maybe; + live?: Maybe; + performance_objectives?: Maybe; + slug?: Maybe; + /** Erläuterung der Ausgangslage */ + starting_position: Scalars['String']; + tasks?: Maybe; + title?: Maybe; + translation_key?: Maybe; }; -export type ChoiceBlock = StreamFieldInterface & { - __typename?: "ChoiceBlock"; - blockType: Scalars["String"]; - choices: Array; - field: Scalars["String"]; - id?: Maybe; - rawValue: Scalars["String"]; - value: Scalars["String"]; +/** An enumeration. */ +export enum CoreUserLanguageChoices { + /** Deutsch */ + De = 'DE', + /** Français */ + Fr = 'FR', + /** Italiano */ + It = 'IT' +} + +export type CoursePageInterface = { + content_type?: Maybe; + frontend_url?: Maybe; + id?: Maybe; + live?: Maybe; + slug?: Maybe; + title?: Maybe; + translation_key?: Maybe; }; -export type ChoiceOption = { - __typename?: "ChoiceOption"; - key: Scalars["String"]; - value: Scalars["String"]; -}; - -export type Circle = PageInterface & { - __typename?: "Circle"; - aliasOf?: Maybe; - ancestors: Array; - children: Array; - contentType: Scalars["String"]; - depth?: Maybe; - descendants: Array; - draftTitle: Scalars["String"]; - expireAt?: Maybe; - expired: Scalars["Boolean"]; - firstPublishedAt?: Maybe; - goLiveAt?: Maybe; - hasUnpublishedChanges: Scalars["Boolean"]; - id?: Maybe; - lastPublishedAt?: Maybe; - latestRevisionCreatedAt?: Maybe; - live: Scalars["Boolean"]; - locked?: Maybe; - lockedAt?: Maybe; - lockedBy?: Maybe; - nextSiblings: Array; - numchild: Scalars["Int"]; - owner?: Maybe; - pageType?: Maybe; - parent?: Maybe; - path: Scalars["String"]; - previousSiblings: Array; - searchDescription?: Maybe; - seoTitle: Scalars["String"]; - showInMenus: Scalars["Boolean"]; - siblings: Array; - slug: Scalars["String"]; - title: Scalars["String"]; - translationKey: Scalars["UUID"]; - url?: Maybe; - urlPath: Scalars["String"]; -}; - -export type CircleAncestorsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type CircleChildrenArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type CircleDescendantsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type CircleNextSiblingsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type CirclePreviousSiblingsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type CircleSiblingsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type CircleDocument = { - __typename?: "CircleDocument"; - id?: Maybe; -}; - -export type CollectionObjectType = { - __typename?: "CollectionObjectType"; - ancestors: Array>; - depth: Scalars["Int"]; - descendants: Array>; - id: Scalars["ID"]; - name: Scalars["String"]; - numchild: Scalars["Int"]; - path: Scalars["String"]; -}; - -export type CompetencePage = PageInterface & { - __typename?: "CompetencePage"; - aliasOf?: Maybe; - ancestors: Array; - children: Array; - contentType: Scalars["String"]; - depth?: Maybe; - descendants: Array; - draftTitle: Scalars["String"]; - expireAt?: Maybe; - expired: Scalars["Boolean"]; - firstPublishedAt?: Maybe; - goLiveAt?: Maybe; - hasUnpublishedChanges: Scalars["Boolean"]; - id?: Maybe; - lastPublishedAt?: Maybe; - latestRevisionCreatedAt?: Maybe; - live: Scalars["Boolean"]; - locked?: Maybe; - lockedAt?: Maybe; - lockedBy?: Maybe; - nextSiblings: Array; - numchild: Scalars["Int"]; - owner?: Maybe; - pageType?: Maybe; - parent?: Maybe; - path: Scalars["String"]; - previousSiblings: Array; - searchDescription?: Maybe; - seoTitle: Scalars["String"]; - showInMenus: Scalars["Boolean"]; - siblings: Array; - slug: Scalars["String"]; - title: Scalars["String"]; - translationKey: Scalars["UUID"]; - url?: Maybe; - urlPath: Scalars["String"]; -}; - -export type CompetencePageAncestorsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type CompetencePageChildrenArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type CompetencePageDescendantsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type CompetencePageNextSiblingsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type CompetencePagePreviousSiblingsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type CompetencePageSiblingsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type CompetenceProfilePage = PageInterface & { - __typename?: "CompetenceProfilePage"; - aliasOf?: Maybe; - ancestors: Array; - children: Array; - contentType: Scalars["String"]; - depth?: Maybe; - descendants: Array; - draftTitle: Scalars["String"]; - expireAt?: Maybe; - expired: Scalars["Boolean"]; - firstPublishedAt?: Maybe; - goLiveAt?: Maybe; - hasUnpublishedChanges: Scalars["Boolean"]; - id?: Maybe; - lastPublishedAt?: Maybe; - latestRevisionCreatedAt?: Maybe; - live: Scalars["Boolean"]; - locked?: Maybe; - lockedAt?: Maybe; - lockedBy?: Maybe; - nextSiblings: Array; - numchild: Scalars["Int"]; - owner?: Maybe; - pageType?: Maybe; - parent?: Maybe; - path: Scalars["String"]; - previousSiblings: Array; - searchDescription?: Maybe; - seoTitle: Scalars["String"]; - showInMenus: Scalars["Boolean"]; - siblings: Array; - slug: Scalars["String"]; - title: Scalars["String"]; - translationKey: Scalars["UUID"]; - url?: Maybe; - urlPath: Scalars["String"]; -}; - -export type CompetenceProfilePageAncestorsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type CompetenceProfilePageChildrenArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type CompetenceProfilePageDescendantsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type CompetenceProfilePageNextSiblingsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type CompetenceProfilePagePreviousSiblingsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type CompetenceProfilePageSiblingsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type Course = { - __typename?: "Course"; - id?: Maybe; -}; - -export type CourseCategory = { - __typename?: "CourseCategory"; - id?: Maybe; -}; - -export type CourseCompletion = { - __typename?: "CourseCompletion"; - id?: Maybe; -}; - -export type CoursePage = PageInterface & { - __typename?: "CoursePage"; - aliasOf?: Maybe; - ancestors: Array; - children: Array; - contentType: Scalars["String"]; - depth?: Maybe; - descendants: Array; - draftTitle: Scalars["String"]; - expireAt?: Maybe; - expired: Scalars["Boolean"]; - firstPublishedAt?: Maybe; - goLiveAt?: Maybe; - hasUnpublishedChanges: Scalars["Boolean"]; - id?: Maybe; - lastPublishedAt?: Maybe; - latestRevisionCreatedAt?: Maybe; - live: Scalars["Boolean"]; - locked?: Maybe; - lockedAt?: Maybe; - lockedBy?: Maybe; - nextSiblings: Array; - numchild: Scalars["Int"]; - owner?: Maybe; - pageType?: Maybe; - parent?: Maybe; - path: Scalars["String"]; - previousSiblings: Array; - searchDescription?: Maybe; - seoTitle: Scalars["String"]; - showInMenus: Scalars["Boolean"]; - siblings: Array; - slug: Scalars["String"]; - title: Scalars["String"]; - translationKey: Scalars["UUID"]; - url?: Maybe; - urlPath: Scalars["String"]; -}; - -export type CoursePageAncestorsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type CoursePageChildrenArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type CoursePageDescendantsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type CoursePageNextSiblingsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type CoursePagePreviousSiblingsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type CoursePageSiblingsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type CourseSession = { - __typename?: "CourseSession"; - id?: Maybe; -}; - -export type CourseSessionUser = { - __typename?: "CourseSessionUser"; - id?: Maybe; -}; - -export type DateBlock = StreamFieldInterface & { - __typename?: "DateBlock"; - blockType: Scalars["String"]; - field: Scalars["String"]; - id?: Maybe; - rawValue: Scalars["String"]; - value: Scalars["String"]; -}; - -export type DateBlockValueArgs = { - format?: InputMaybe; -}; - -export type DateTimeBlock = StreamFieldInterface & { - __typename?: "DateTimeBlock"; - blockType: Scalars["String"]; - field: Scalars["String"]; - id?: Maybe; - rawValue: Scalars["String"]; - value: Scalars["String"]; -}; - -export type DateTimeBlockValueArgs = { - format?: InputMaybe; -}; - -export type DecimalBlock = StreamFieldInterface & { - __typename?: "DecimalBlock"; - blockType: Scalars["String"]; - field: Scalars["String"]; - id?: Maybe; - rawValue: Scalars["String"]; - value: Scalars["Float"]; -}; - -export type DocumentChooserBlock = StreamFieldInterface & { - __typename?: "DocumentChooserBlock"; - blockType: Scalars["String"]; - document: LibraryDocument; - field: Scalars["String"]; - id?: Maybe; - rawValue: Scalars["String"]; -}; - -export type EmailBlock = StreamFieldInterface & { - __typename?: "EmailBlock"; - blockType: Scalars["String"]; - field: Scalars["String"]; - id?: Maybe; - rawValue: Scalars["String"]; - value: Scalars["String"]; -}; - -export type EmbedBlock = StreamFieldInterface & { - __typename?: "EmbedBlock"; - blockType: Scalars["String"]; - embed?: Maybe; - field: Scalars["String"]; - id?: Maybe; - rawEmbed?: Maybe; - rawValue: Scalars["String"]; - url: Scalars["String"]; - value: Scalars["String"]; +export type CourseType = { + __typename?: 'CourseType'; + category_name: Scalars['String']; + id: Scalars['ID']; + learning_path?: Maybe; + slug: Scalars['String']; + title: Scalars['String']; }; export type ErrorType = { - __typename?: "ErrorType"; - field: Scalars["String"]; - messages: Array; + __typename?: 'ErrorType'; + field: Scalars['String']; + messages: Array; }; export type FeedbackResponse = Node & { - __typename?: "FeedbackResponse"; - circle: Circle; - courseSession: CourseSession; - data?: Maybe; - id: Scalars["ID"]; + __typename?: 'FeedbackResponse'; + created_at: Scalars['DateTime']; + data?: Maybe; + /** The ID of the object */ + id: Scalars['ID']; }; -export type FloatBlock = StreamFieldInterface & { - __typename?: "FloatBlock"; - blockType: Scalars["String"]; - field: Scalars["String"]; - id?: Maybe; - rawValue: Scalars["String"]; - value: Scalars["Float"]; -}; - -export type ImageChooserBlock = StreamFieldInterface & { - __typename?: "ImageChooserBlock"; - blockType: Scalars["String"]; - field: Scalars["String"]; - id?: Maybe; - image: ImageObjectType; - rawValue: Scalars["String"]; -}; - -export type ImageObjectType = { - __typename?: "ImageObjectType"; - aspectRatio: Scalars["Float"]; - collection: CollectionObjectType; - createdAt: Scalars["DateTime"]; - file: Scalars["String"]; - fileHash: Scalars["String"]; - fileSize?: Maybe; - focalPointHeight?: Maybe; - focalPointWidth?: Maybe; - focalPointX?: Maybe; - focalPointY?: Maybe; - height: Scalars["Int"]; - id: Scalars["ID"]; - rendition?: Maybe; - renditions: Array; - sizes: Scalars["String"]; - /** @deprecated Use the `url` attribute */ - src: Scalars["String"]; - srcSet?: Maybe; - tags: Array; - title: Scalars["String"]; - uploadedByUser?: Maybe; - url: Scalars["String"]; - width: Scalars["Int"]; -}; - -export type ImageObjectTypeRenditionArgs = { - bgcolor?: InputMaybe; - fill?: InputMaybe; - format?: InputMaybe; - height?: InputMaybe; - jpegquality?: InputMaybe; - max?: InputMaybe; - min?: InputMaybe; - webpquality?: InputMaybe; - width?: InputMaybe; -}; - -export type ImageObjectTypeSrcSetArgs = { - format?: InputMaybe; - sizes?: InputMaybe>>; -}; - -export type ImageRenditionObjectType = { - __typename?: "ImageRenditionObjectType"; - aspectRatio: Scalars["Float"]; - collection: CollectionObjectType; - createdAt: Scalars["DateTime"]; - file: Scalars["String"]; - fileHash: Scalars["String"]; - fileSize?: Maybe; - filterSpec: Scalars["String"]; - focalPointHeight?: Maybe; - focalPointKey: Scalars["String"]; - focalPointWidth?: Maybe; - focalPointX?: Maybe; - focalPointY?: Maybe; - height: Scalars["Int"]; - id: Scalars["ID"]; - image: ImageObjectType; - sizes: Scalars["String"]; - /** @deprecated Use the `url` attribute */ - src: Scalars["String"]; - tags: Array; - title: Scalars["String"]; - url: Scalars["String"]; - width: Scalars["Int"]; -}; - -export type IntegerBlock = StreamFieldInterface & { - __typename?: "IntegerBlock"; - blockType: Scalars["String"]; - field: Scalars["String"]; - id?: Maybe; - rawValue: Scalars["String"]; - value: Scalars["Int"]; -}; - -export type LearningContent = PageInterface & { - __typename?: "LearningContent"; - aliasOf?: Maybe; - ancestors: Array; - children: Array; - contentType: Scalars["String"]; - depth?: Maybe; - descendants: Array; - draftTitle: Scalars["String"]; - expireAt?: Maybe; - expired: Scalars["Boolean"]; - firstPublishedAt?: Maybe; - goLiveAt?: Maybe; - hasUnpublishedChanges: Scalars["Boolean"]; - id?: Maybe; - lastPublishedAt?: Maybe; - latestRevisionCreatedAt?: Maybe; - live: Scalars["Boolean"]; - locked?: Maybe; - lockedAt?: Maybe; - lockedBy?: Maybe; - nextSiblings: Array; - numchild: Scalars["Int"]; - owner?: Maybe; - pageType?: Maybe; - parent?: Maybe; - path: Scalars["String"]; - previousSiblings: Array; - searchDescription?: Maybe; - seoTitle: Scalars["String"]; - showInMenus: Scalars["Boolean"]; - siblings: Array; - slug: Scalars["String"]; - title: Scalars["String"]; - translationKey: Scalars["UUID"]; - url?: Maybe; - urlPath: Scalars["String"]; -}; - -export type LearningContentAncestorsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type LearningContentChildrenArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type LearningContentDescendantsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type LearningContentNextSiblingsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type LearningContentPreviousSiblingsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type LearningContentSiblingsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type LearningPath = PageInterface & { - __typename?: "LearningPath"; - aliasOf?: Maybe; - ancestors: Array; - children: Array; - contentType: Scalars["String"]; - depth?: Maybe; - descendants: Array; - draftTitle: Scalars["String"]; - expireAt?: Maybe; - expired: Scalars["Boolean"]; - firstPublishedAt?: Maybe; - goLiveAt?: Maybe; - hasUnpublishedChanges: Scalars["Boolean"]; - id?: Maybe; - lastPublishedAt?: Maybe; - latestRevisionCreatedAt?: Maybe; - live: Scalars["Boolean"]; - locked?: Maybe; - lockedAt?: Maybe; - lockedBy?: Maybe; - nextSiblings: Array; - numchild: Scalars["Int"]; - owner?: Maybe; - pageType?: Maybe; - parent?: Maybe; - path: Scalars["String"]; - previousSiblings: Array; - searchDescription?: Maybe; - seoTitle: Scalars["String"]; - showInMenus: Scalars["Boolean"]; - siblings: Array; - slug: Scalars["String"]; - title: Scalars["String"]; - translationKey: Scalars["UUID"]; - url?: Maybe; - urlPath: Scalars["String"]; -}; - -export type LearningPathAncestorsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type LearningPathChildrenArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type LearningPathDescendantsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type LearningPathNextSiblingsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type LearningPathPreviousSiblingsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type LearningPathSiblingsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type LearningSequence = PageInterface & { - __typename?: "LearningSequence"; - aliasOf?: Maybe; - ancestors: Array; - children: Array; - contentType: Scalars["String"]; - depth?: Maybe; - descendants: Array; - draftTitle: Scalars["String"]; - expireAt?: Maybe; - expired: Scalars["Boolean"]; - firstPublishedAt?: Maybe; - goLiveAt?: Maybe; - hasUnpublishedChanges: Scalars["Boolean"]; - id?: Maybe; - lastPublishedAt?: Maybe; - latestRevisionCreatedAt?: Maybe; - live: Scalars["Boolean"]; - locked?: Maybe; - lockedAt?: Maybe; - lockedBy?: Maybe; - nextSiblings: Array; - numchild: Scalars["Int"]; - owner?: Maybe; - pageType?: Maybe; - parent?: Maybe; - path: Scalars["String"]; - previousSiblings: Array; - searchDescription?: Maybe; - seoTitle: Scalars["String"]; - showInMenus: Scalars["Boolean"]; - siblings: Array; - slug: Scalars["String"]; - title: Scalars["String"]; - translationKey: Scalars["UUID"]; - url?: Maybe; - urlPath: Scalars["String"]; -}; - -export type LearningSequenceAncestorsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type LearningSequenceChildrenArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type LearningSequenceDescendantsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type LearningSequenceNextSiblingsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type LearningSequencePreviousSiblingsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type LearningSequenceSiblingsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type LearningUnit = PageInterface & { - __typename?: "LearningUnit"; - aliasOf?: Maybe; - ancestors: Array; - children: Array; - contentType: Scalars["String"]; - depth?: Maybe; - descendants: Array; - draftTitle: Scalars["String"]; - expireAt?: Maybe; - expired: Scalars["Boolean"]; - firstPublishedAt?: Maybe; - goLiveAt?: Maybe; - hasUnpublishedChanges: Scalars["Boolean"]; - id?: Maybe; - lastPublishedAt?: Maybe; - latestRevisionCreatedAt?: Maybe; - live: Scalars["Boolean"]; - locked?: Maybe; - lockedAt?: Maybe; - lockedBy?: Maybe; - nextSiblings: Array; - numchild: Scalars["Int"]; - owner?: Maybe; - pageType?: Maybe; - parent?: Maybe; - path: Scalars["String"]; - previousSiblings: Array; - searchDescription?: Maybe; - seoTitle: Scalars["String"]; - showInMenus: Scalars["Boolean"]; - siblings: Array; - slug: Scalars["String"]; - title: Scalars["String"]; - translationKey: Scalars["UUID"]; - url?: Maybe; - urlPath: Scalars["String"]; -}; - -export type LearningUnitAncestorsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type LearningUnitChildrenArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type LearningUnitDescendantsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type LearningUnitNextSiblingsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type LearningUnitPreviousSiblingsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type LearningUnitSiblingsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type LibraryDocument = { - __typename?: "LibraryDocument"; - collection: CollectionObjectType; - createdAt: Scalars["DateTime"]; - file: Scalars["String"]; - fileHash: Scalars["String"]; - fileSize?: Maybe; - id?: Maybe; - tags: Array; - title: Scalars["String"]; - url: Scalars["String"]; -}; - -export type ListBlock = StreamFieldInterface & { - __typename?: "ListBlock"; - blockType: Scalars["String"]; - field: Scalars["String"]; - id?: Maybe; - items: Array; - rawValue: Scalars["String"]; -}; - -export type MediaCategoryPage = PageInterface & { - __typename?: "MediaCategoryPage"; - aliasOf?: Maybe; - ancestors: Array; - children: Array; - contentType: Scalars["String"]; - depth?: Maybe; - descendants: Array; - draftTitle: Scalars["String"]; - expireAt?: Maybe; - expired: Scalars["Boolean"]; - firstPublishedAt?: Maybe; - goLiveAt?: Maybe; - hasUnpublishedChanges: Scalars["Boolean"]; - id?: Maybe; - lastPublishedAt?: Maybe; - latestRevisionCreatedAt?: Maybe; - live: Scalars["Boolean"]; - locked?: Maybe; - lockedAt?: Maybe; - lockedBy?: Maybe; - nextSiblings: Array; - numchild: Scalars["Int"]; - owner?: Maybe; - pageType?: Maybe; - parent?: Maybe; - path: Scalars["String"]; - previousSiblings: Array; - searchDescription?: Maybe; - seoTitle: Scalars["String"]; - showInMenus: Scalars["Boolean"]; - siblings: Array; - slug: Scalars["String"]; - title: Scalars["String"]; - translationKey: Scalars["UUID"]; - url?: Maybe; - urlPath: Scalars["String"]; -}; - -export type MediaCategoryPageAncestorsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type MediaCategoryPageChildrenArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type MediaCategoryPageDescendantsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type MediaCategoryPageNextSiblingsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type MediaCategoryPagePreviousSiblingsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type MediaCategoryPageSiblingsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type MediaLibraryPage = PageInterface & { - __typename?: "MediaLibraryPage"; - aliasOf?: Maybe; - ancestors: Array; - children: Array; - contentType: Scalars["String"]; - depth?: Maybe; - descendants: Array; - draftTitle: Scalars["String"]; - expireAt?: Maybe; - expired: Scalars["Boolean"]; - firstPublishedAt?: Maybe; - goLiveAt?: Maybe; - hasUnpublishedChanges: Scalars["Boolean"]; - id?: Maybe; - lastPublishedAt?: Maybe; - latestRevisionCreatedAt?: Maybe; - live: Scalars["Boolean"]; - locked?: Maybe; - lockedAt?: Maybe; - lockedBy?: Maybe; - nextSiblings: Array; - numchild: Scalars["Int"]; - owner?: Maybe; - pageType?: Maybe; - parent?: Maybe; - path: Scalars["String"]; - previousSiblings: Array; - searchDescription?: Maybe; - seoTitle: Scalars["String"]; - showInMenus: Scalars["Boolean"]; - siblings: Array; - slug: Scalars["String"]; - title: Scalars["String"]; - translationKey: Scalars["UUID"]; - url?: Maybe; - urlPath: Scalars["String"]; -}; - -export type MediaLibraryPageAncestorsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type MediaLibraryPageChildrenArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type MediaLibraryPageDescendantsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type MediaLibraryPageNextSiblingsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type MediaLibraryPagePreviousSiblingsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type MediaLibraryPageSiblingsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; +export type LearningPathType = CoursePageInterface & { + __typename?: 'LearningPathType'; + content_type?: Maybe; + depth: Scalars['Int']; + draft_title: Scalars['String']; + expire_at?: Maybe; + expired: Scalars['Boolean']; + first_published_at?: Maybe; + frontend_url?: Maybe; + go_live_at?: Maybe; + has_unpublished_changes: Scalars['Boolean']; + id?: Maybe; + last_published_at?: Maybe; + latest_revision_created_at?: Maybe; + live?: Maybe; + locked: Scalars['Boolean']; + locked_at?: Maybe; + locked_by?: Maybe; + numchild: Scalars['Int']; + owner?: Maybe; + path: Scalars['String']; + /** Die informative Beschreibung, dargestellt in Suchmaschinen-Ergebnissen unter der Überschrift. */ + search_description: Scalars['String']; + /** Der Titel der Seite, dargestellt in Suchmaschinen-Ergebnissen als die verlinkte Überschrift. */ + seo_title: Scalars['String']; + /** Ob ein Link zu dieser Seite in automatisch generierten Menüs auftaucht. */ + show_in_menus: Scalars['Boolean']; + slug?: Maybe; + title?: Maybe; + translation_key?: Maybe; + url_path: Scalars['String']; }; export type Mutation = { - __typename?: "Mutation"; - sendFeedback?: Maybe; + __typename?: 'Mutation'; + send_feedback?: Maybe; + upsert_assignment_completion?: Maybe; }; -export type MutationSendFeedbackArgs = { + +export type MutationSend_FeedbackArgs = { input: SendFeedbackInput; }; + +export type MutationUpsert_Assignment_CompletionArgs = { + assignment_id: Scalars['ID']; + assignment_user_id?: InputMaybe; + completion_data_string?: InputMaybe; + completion_status?: InputMaybe; + course_session_id: Scalars['ID']; + evaluation_grade?: InputMaybe; + evaluation_points?: InputMaybe; +}; + +/** An object with an ID */ export type Node = { - id: Scalars["ID"]; -}; - -export type Page = PageInterface & { - __typename?: "Page"; - aliasOf?: Maybe; - aliases: Array; - ancestors: Array; - children: Array; - circle?: Maybe; - competencepage?: Maybe; - competenceprofilepage?: Maybe; - contentType: Scalars["String"]; - coursepage?: Maybe; - depth?: Maybe; - descendants: Array; - draftTitle: Scalars["String"]; - expireAt?: Maybe; - expired: Scalars["Boolean"]; - firstPublishedAt?: Maybe; - goLiveAt?: Maybe; - hasUnpublishedChanges: Scalars["Boolean"]; - id?: Maybe; - lastPublishedAt?: Maybe; - latestRevisionCreatedAt?: Maybe; - learningcontent?: Maybe; - learningpath?: Maybe; - learningsequence?: Maybe; - learningunit?: Maybe; - live: Scalars["Boolean"]; - locked?: Maybe; - lockedAt?: Maybe; - lockedBy?: Maybe; - mediacategorypage?: Maybe; - medialibrarypage?: Maybe; - nextSiblings: Array; - numchild: Scalars["Int"]; - owner?: Maybe; - pageType?: Maybe; - parent?: Maybe; - path: Scalars["String"]; - performancecriteria?: Maybe; - previousSiblings: Array; - searchDescription?: Maybe; - seoTitle: Scalars["String"]; - showInMenus: Scalars["Boolean"]; - siblings: Array; - sitesRootedHere: Array; - slug: Scalars["String"]; - title: Scalars["String"]; - topic?: Maybe; - translationKey: Scalars["UUID"]; - url?: Maybe; - urlPath: Scalars["String"]; -}; - -export type PageAncestorsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type PageChildrenArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type PageDescendantsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type PageNextSiblingsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type PagePreviousSiblingsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type PageSiblingsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type PageChooserBlock = StreamFieldInterface & { - __typename?: "PageChooserBlock"; - blockType: Scalars["String"]; - field: Scalars["String"]; - id?: Maybe; - page: PageInterface; - rawValue: Scalars["String"]; -}; - -export type PageInterface = { - ancestors: Array; - children: Array; - contentType: Scalars["String"]; - depth?: Maybe; - descendants: Array; - firstPublishedAt?: Maybe; - id?: Maybe; - lastPublishedAt?: Maybe; - live: Scalars["Boolean"]; - locked?: Maybe; - nextSiblings: Array; - pageType?: Maybe; - parent?: Maybe; - previousSiblings: Array; - searchDescription?: Maybe; - seoTitle: Scalars["String"]; - showInMenus: Scalars["Boolean"]; - siblings: Array; - slug: Scalars["String"]; - title: Scalars["String"]; - url?: Maybe; - urlPath: Scalars["String"]; -}; - -export type PageInterfaceAncestorsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type PageInterfaceChildrenArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type PageInterfaceDescendantsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type PageInterfaceNextSiblingsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type PageInterfacePreviousSiblingsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type PageInterfaceSiblingsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type PerformanceCriteria = PageInterface & { - __typename?: "PerformanceCriteria"; - aliasOf?: Maybe; - ancestors: Array; - children: Array; - contentType: Scalars["String"]; - depth?: Maybe; - descendants: Array; - draftTitle: Scalars["String"]; - expireAt?: Maybe; - expired: Scalars["Boolean"]; - firstPublishedAt?: Maybe; - goLiveAt?: Maybe; - hasUnpublishedChanges: Scalars["Boolean"]; - id?: Maybe; - lastPublishedAt?: Maybe; - latestRevisionCreatedAt?: Maybe; - live: Scalars["Boolean"]; - locked?: Maybe; - lockedAt?: Maybe; - lockedBy?: Maybe; - nextSiblings: Array; - numchild: Scalars["Int"]; - owner?: Maybe; - pageType?: Maybe; - parent?: Maybe; - path: Scalars["String"]; - previousSiblings: Array; - searchDescription?: Maybe; - seoTitle: Scalars["String"]; - showInMenus: Scalars["Boolean"]; - siblings: Array; - slug: Scalars["String"]; - title: Scalars["String"]; - translationKey: Scalars["UUID"]; - url?: Maybe; - urlPath: Scalars["String"]; -}; - -export type PerformanceCriteriaAncestorsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type PerformanceCriteriaChildrenArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type PerformanceCriteriaDescendantsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type PerformanceCriteriaNextSiblingsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type PerformanceCriteriaPreviousSiblingsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type PerformanceCriteriaSiblingsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; + /** The ID of the object */ + id: Scalars['ID']; }; export type Query = { - __typename?: "Query"; - collections: Array>; - document?: Maybe; - documentType: Scalars["String"]; - documents: Array; - image?: Maybe; - imageType: Scalars["String"]; - images: Array; - page?: Maybe; - pages: Array; - redirects: Array; - search: Array; - site?: Maybe; - sites: Array; - tag?: Maybe; - tags: Array; + __typename?: 'Query'; + assignment?: Maybe; + assignment_completion?: Maybe; + course?: Maybe; }; -export type QueryCollectionsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; + +export type QueryAssignmentArgs = { + id?: InputMaybe; + slug?: InputMaybe; }; -export type QueryDocumentArgs = { - id?: InputMaybe; + +export type QueryAssignment_CompletionArgs = { + assignment_id: Scalars['ID']; + assignment_user_id?: InputMaybe; + course_session_id: Scalars['ID']; }; -export type QueryDocumentsArgs = { - collection?: InputMaybe; - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; -export type QueryImageArgs = { - id?: InputMaybe; -}; - -export type QueryImagesArgs = { - collection?: InputMaybe; - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type QueryPageArgs = { - contentType?: InputMaybe; - id?: InputMaybe; - inSite?: InputMaybe; - site?: InputMaybe; - slug?: InputMaybe; - token?: InputMaybe; - urlPath?: InputMaybe; -}; - -export type QueryPagesArgs = { - ancestor?: InputMaybe; - contentType?: InputMaybe; - id?: InputMaybe; - inSite?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - parent?: InputMaybe; - searchQuery?: InputMaybe; - site?: InputMaybe; -}; - -export type QuerySearchArgs = { - query?: InputMaybe; -}; - -export type QuerySiteArgs = { - hostname?: InputMaybe; - id?: InputMaybe; -}; - -export type QuerySitesArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type QueryTagArgs = { - id?: InputMaybe; -}; - -export type QueryTagsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; -}; - -export type RawHtmlBlock = StreamFieldInterface & { - __typename?: "RawHTMLBlock"; - blockType: Scalars["String"]; - field: Scalars["String"]; - id?: Maybe; - rawValue: Scalars["String"]; - value: Scalars["String"]; -}; - -export type RedirectType = { - __typename?: "RedirectType"; - isPermanent: Scalars["Boolean"]; - newUrl: Scalars["String"]; - oldPath: Scalars["String"]; - oldUrl: Scalars["String"]; - page?: Maybe; -}; - -export type RegexBlock = StreamFieldInterface & { - __typename?: "RegexBlock"; - blockType: Scalars["String"]; - field: Scalars["String"]; - id?: Maybe; - rawValue: Scalars["String"]; - value: Scalars["String"]; -}; - -export type RichTextBlock = StreamFieldInterface & { - __typename?: "RichTextBlock"; - blockType: Scalars["String"]; - field: Scalars["String"]; - id?: Maybe; - rawValue: Scalars["String"]; - value: Scalars["String"]; -}; - -export type Search = - | Circle - | CircleDocument - | CompetencePage - | CompetenceProfilePage - | Course - | CourseCategory - | CourseCompletion - | CoursePage - | CourseSession - | CourseSessionUser - | LearningContent - | LearningPath - | LearningSequence - | LearningUnit - | LibraryDocument - | MediaCategoryPage - | MediaLibraryPage - | Page - | PerformanceCriteria - | SecurityRequestResponseLog - | Topic - | User; - -export type SecurityRequestResponseLog = { - __typename?: "SecurityRequestResponseLog"; - id?: Maybe; +export type QueryCourseArgs = { + id?: InputMaybe; }; export type SendFeedbackInput = { - clientMutationId?: InputMaybe; - courseSession: Scalars["Int"]; - data?: InputMaybe; - page: Scalars["String"]; + clientMutationId?: InputMaybe; + course_session: Scalars['Int']; + data?: InputMaybe; + page: Scalars['String']; }; export type SendFeedbackPayload = { - __typename?: "SendFeedbackPayload"; - clientMutationId?: Maybe; + __typename?: 'SendFeedbackPayload'; + clientMutationId?: Maybe; + /** May contain more than one error for same field. */ errors?: Maybe>>; - feedbackResponse?: Maybe; + feedback_response?: Maybe; }; -export type SiteObjectType = { - __typename?: "SiteObjectType"; - hostname: Scalars["String"]; - id: Scalars["ID"]; - isDefaultSite: Scalars["Boolean"]; - page?: Maybe; - pages: Array; - port: Scalars["Int"]; - rootPage: Page; - siteName: Scalars["String"]; -}; - -export type SiteObjectTypePageArgs = { - contentType?: InputMaybe; - id?: InputMaybe; - slug?: InputMaybe; - token?: InputMaybe; - urlPath?: InputMaybe; -}; - -export type SiteObjectTypePagesArgs = { - contentType?: InputMaybe; - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type StaticBlock = StreamFieldInterface & { - __typename?: "StaticBlock"; - blockType: Scalars["String"]; - field: Scalars["String"]; - id?: Maybe; - rawValue: Scalars["String"]; - value: Scalars["String"]; -}; - -export type StreamBlock = StreamFieldInterface & { - __typename?: "StreamBlock"; - blockType: Scalars["String"]; - blocks: Array; - field: Scalars["String"]; - id?: Maybe; - rawValue: Scalars["String"]; -}; - -export type StreamFieldBlock = StreamFieldInterface & { - __typename?: "StreamFieldBlock"; - blockType: Scalars["String"]; - field: Scalars["String"]; - id?: Maybe; - rawValue: Scalars["String"]; - value: Scalars["String"]; -}; - -export type StreamFieldInterface = { - blockType: Scalars["String"]; - field: Scalars["String"]; - id?: Maybe; - rawValue: Scalars["String"]; -}; - -export type StructBlock = StreamFieldInterface & { - __typename?: "StructBlock"; - blockType: Scalars["String"]; - blocks: Array; - field: Scalars["String"]; - id?: Maybe; - rawValue: Scalars["String"]; -}; - -export type TagObjectType = { - __typename?: "TagObjectType"; - id: Scalars["ID"]; - name: Scalars["String"]; -}; - -export type TextBlock = StreamFieldInterface & { - __typename?: "TextBlock"; - blockType: Scalars["String"]; - field: Scalars["String"]; - id?: Maybe; - rawValue: Scalars["String"]; - value: Scalars["String"]; -}; - -export type TimeBlock = StreamFieldInterface & { - __typename?: "TimeBlock"; - blockType: Scalars["String"]; - field: Scalars["String"]; - id?: Maybe; - rawValue: Scalars["String"]; - value: Scalars["String"]; -}; - -export type TimeBlockValueArgs = { - format?: InputMaybe; -}; - -export type Topic = PageInterface & { - __typename?: "Topic"; - aliasOf?: Maybe; - ancestors: Array; - children: Array; - contentType: Scalars["String"]; - depth?: Maybe; - descendants: Array; - draftTitle: Scalars["String"]; - expireAt?: Maybe; - expired: Scalars["Boolean"]; - firstPublishedAt?: Maybe; - goLiveAt?: Maybe; - hasUnpublishedChanges: Scalars["Boolean"]; - id?: Maybe; - lastPublishedAt?: Maybe; - latestRevisionCreatedAt?: Maybe; - live: Scalars["Boolean"]; - locked?: Maybe; - lockedAt?: Maybe; - lockedBy?: Maybe; - nextSiblings: Array; - numchild: Scalars["Int"]; - owner?: Maybe; - pageType?: Maybe; - parent?: Maybe; - path: Scalars["String"]; - previousSiblings: Array; - searchDescription?: Maybe; - seoTitle: Scalars["String"]; - showInMenus: Scalars["Boolean"]; - siblings: Array; - slug: Scalars["String"]; - title: Scalars["String"]; - translationKey: Scalars["UUID"]; - url?: Maybe; - urlPath: Scalars["String"]; -}; - -export type TopicAncestorsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type TopicChildrenArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type TopicDescendantsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type TopicNextSiblingsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type TopicPreviousSiblingsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type TopicSiblingsArgs = { - id?: InputMaybe; - limit?: InputMaybe; - offset?: InputMaybe; - order?: InputMaybe; - searchQuery?: InputMaybe; -}; - -export type UrlBlock = StreamFieldInterface & { - __typename?: "URLBlock"; - blockType: Scalars["String"]; - field: Scalars["String"]; - id?: Maybe; - rawValue: Scalars["String"]; - value: Scalars["String"]; -}; - -export type User = { - __typename?: "User"; - id?: Maybe; +export type UserType = { + __typename?: 'UserType'; + avatar_url: Scalars['String']; + email: Scalars['String']; + first_name: Scalars['String']; + id: Scalars['ID']; + language: CoreUserLanguageChoices; + last_name: Scalars['String']; + /** Erforderlich. 150 Zeichen oder weniger. Nur Buchstaben, Ziffern und @/./+/-/_. */ + username: Scalars['String']; }; export type SendFeedbackMutationMutationVariables = Exact<{ input: SendFeedbackInput; }>; -export type SendFeedbackMutationMutation = { - __typename?: "Mutation"; - sendFeedback?: { - __typename?: "SendFeedbackPayload"; - feedbackResponse?: { __typename?: "FeedbackResponse"; id: string } | null; - errors?: Array<{ - __typename?: "ErrorType"; - field: string; - messages: Array; - } | null> | null; - } | null; -}; -export const SendFeedbackMutationDocument = { - kind: "Document", - definitions: [ - { - kind: "OperationDefinition", - operation: "mutation", - name: { kind: "Name", value: "SendFeedbackMutation" }, - variableDefinitions: [ - { - kind: "VariableDefinition", - variable: { kind: "Variable", name: { kind: "Name", value: "input" } }, - type: { - kind: "NonNullType", - type: { - kind: "NamedType", - name: { kind: "Name", value: "SendFeedbackInput" }, - }, - }, - }, - ], - selectionSet: { - kind: "SelectionSet", - selections: [ - { - kind: "Field", - name: { kind: "Name", value: "sendFeedback" }, - arguments: [ - { - kind: "Argument", - name: { kind: "Name", value: "input" }, - value: { kind: "Variable", name: { kind: "Name", value: "input" } }, - }, - ], - selectionSet: { - kind: "SelectionSet", - selections: [ - { - kind: "Field", - name: { kind: "Name", value: "feedbackResponse" }, - selectionSet: { - kind: "SelectionSet", - selections: [ - { kind: "Field", name: { kind: "Name", value: "id" } }, - ], - }, - }, - { - kind: "Field", - name: { kind: "Name", value: "errors" }, - selectionSet: { - kind: "SelectionSet", - selections: [ - { kind: "Field", name: { kind: "Name", value: "field" } }, - { kind: "Field", name: { kind: "Name", value: "messages" } }, - ], - }, - }, - ], - }, - }, - ], - }, - }, - ], -} as unknown as DocumentNode< - SendFeedbackMutationMutation, - SendFeedbackMutationMutationVariables ->; +export type SendFeedbackMutationMutation = { __typename?: 'Mutation', send_feedback?: { __typename?: 'SendFeedbackPayload', feedback_response?: { __typename?: 'FeedbackResponse', id: string } | null, errors?: Array<{ __typename?: 'ErrorType', field: string, messages: Array } | null> | null } | null }; + +export type UpsertAssignmentCompletionMutationVariables = Exact<{ + assignmentId: Scalars['ID']; + courseSessionId: Scalars['ID']; + assignmentUserId?: InputMaybe; + completionStatus: Scalars['String']; + completionDataString: Scalars['String']; + evaluationGrade?: InputMaybe; + evaluationPoints?: InputMaybe; +}>; + + +export type UpsertAssignmentCompletionMutation = { __typename?: 'Mutation', upsert_assignment_completion?: { __typename?: 'AssignmentCompletionMutation', assignment_completion?: { __typename?: 'AssignmentCompletionType', id: string, completion_status: AssignmentAssignmentCompletionCompletionStatusChoices, submitted_at?: any | null, evaluation_submitted_at?: any | null, evaluation_grade?: number | null, evaluation_points?: number | null, completion_data?: any | null } | null } | null }; + +export type AssignmentCompletionQueryQueryVariables = Exact<{ + assignmentId: Scalars['ID']; + courseSessionId: Scalars['ID']; + assignmentUserId?: InputMaybe; +}>; + + +export type AssignmentCompletionQueryQuery = { __typename?: 'Query', assignment?: { __typename?: 'AssignmentType', id?: string | null, content_type?: string | null, evaluation_description: string, evaluation_document_url: string, evaluation_tasks?: any | null, performance_objectives?: any | null, starting_position: string, tasks?: any | null, title?: string | null, translation_key?: string | null, slug?: string | null } | null, assignment_completion?: { __typename?: 'AssignmentCompletionType', id: string, completion_status: AssignmentAssignmentCompletionCompletionStatusChoices, submitted_at?: any | null, evaluation_submitted_at?: any | null, evaluation_grade?: number | null, evaluation_points?: number | null, completion_data?: any | null, evaluation_user?: { __typename?: 'UserType', id: string } | null, assignment_user: { __typename?: 'UserType', id: string } } | null }; + +export type CourseQueryQueryVariables = Exact<{ + courseId: Scalars['Int']; +}>; + + +export type CourseQueryQuery = { __typename?: 'Query', course?: { __typename?: 'CourseType', id: string, slug: string, title: string, category_name: string, learning_path?: { __typename?: 'LearningPathType', id?: string | null } | null } | null }; + + +export const SendFeedbackMutationDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"SendFeedbackMutation"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"SendFeedbackInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"send_feedback"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"feedback_response"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"Field","name":{"kind":"Name","value":"errors"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"field"}},{"kind":"Field","name":{"kind":"Name","value":"messages"}}]}}]}}]}}]} as unknown as DocumentNode; +export const UpsertAssignmentCompletionDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpsertAssignmentCompletion"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"assignmentId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"assignmentUserId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"completionStatus"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"completionDataString"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"evaluationGrade"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Float"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"evaluationPoints"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Float"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"upsert_assignment_completion"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"assignment_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"assignmentId"}}},{"kind":"Argument","name":{"kind":"Name","value":"course_session_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}}},{"kind":"Argument","name":{"kind":"Name","value":"assignment_user_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"assignmentUserId"}}},{"kind":"Argument","name":{"kind":"Name","value":"completion_status"},"value":{"kind":"Variable","name":{"kind":"Name","value":"completionStatus"}}},{"kind":"Argument","name":{"kind":"Name","value":"completion_data_string"},"value":{"kind":"Variable","name":{"kind":"Name","value":"completionDataString"}}},{"kind":"Argument","name":{"kind":"Name","value":"evaluation_grade"},"value":{"kind":"Variable","name":{"kind":"Name","value":"evaluationGrade"}}},{"kind":"Argument","name":{"kind":"Name","value":"evaluation_points"},"value":{"kind":"Variable","name":{"kind":"Name","value":"evaluationPoints"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"assignment_completion"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"completion_status"}},{"kind":"Field","name":{"kind":"Name","value":"submitted_at"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_submitted_at"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_grade"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_points"}},{"kind":"Field","name":{"kind":"Name","value":"completion_data"}}]}}]}}]}}]} as unknown as DocumentNode; +export const AssignmentCompletionQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"assignmentCompletionQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"assignmentId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"assignmentUserId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"assignment"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"assignmentId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"content_type"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_description"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_document_url"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_tasks"}},{"kind":"Field","name":{"kind":"Name","value":"performance_objectives"}},{"kind":"Field","name":{"kind":"Name","value":"starting_position"}},{"kind":"Field","name":{"kind":"Name","value":"tasks"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"translation_key"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}}]}},{"kind":"Field","name":{"kind":"Name","value":"assignment_completion"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"assignment_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"assignmentId"}}},{"kind":"Argument","name":{"kind":"Name","value":"course_session_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}}},{"kind":"Argument","name":{"kind":"Name","value":"assignment_user_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"assignmentUserId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"completion_status"}},{"kind":"Field","name":{"kind":"Name","value":"submitted_at"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_submitted_at"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"Field","name":{"kind":"Name","value":"assignment_user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_grade"}},{"kind":"Field","name":{"kind":"Name","value":"evaluation_points"}},{"kind":"Field","name":{"kind":"Name","value":"completion_data"}}]}}]}}]} as unknown as DocumentNode; +export const CourseQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"courseQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"courseId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"course"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"courseId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"category_name"}},{"kind":"Field","name":{"kind":"Name","value":"learning_path"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}}]} as unknown as DocumentNode; \ No newline at end of file diff --git a/client/src/gql/index.ts b/client/src/gql/index.ts index 0ea4a91c..f5159916 100644 --- a/client/src/gql/index.ts +++ b/client/src/gql/index.ts @@ -1,2 +1,2 @@ export * from "./fragment-masking"; -export * from "./gql"; +export * from "./gql"; \ No newline at end of file diff --git a/client/src/graphql/client.ts b/client/src/graphql/client.ts new file mode 100644 index 00000000..c0daffa7 --- /dev/null +++ b/client/src/graphql/client.ts @@ -0,0 +1,51 @@ +import { devtoolsExchange } from "@urql/devtools"; +import { cacheExchange } from "@urql/exchange-graphcache"; +import { Client, fetchExchange } from "@urql/vue"; + +export const graphqlClient = new Client({ + url: import.meta.env.VITE_GRAPHQL_URL || "/server/graphql/", + exchanges: [ + devtoolsExchange, + cacheExchange({ + updates: { + Mutation: { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + upsert_assignment_completion(result, args, cache, info) { + // will run on every mutation + // console.log("udpates upsert_assignment_completion", result); + }, + }, + }, + optimistic: { + // @ts-ignore, weiss oh nöt... + upsert_assignment_completion(args, cache, info) { + console.log("optimistic upsert_assignment_completion", args, cache, info); + const id = info.variables.id; + if (id) { + const completionData = cache.resolve( + { __typename: "AssignmentCompletionType", id: "1" }, + "completion_data" + ); + return { + __typename: "AssignmentCompletionMutation", + assignment_completion: { + __typename: "AssignmentCompletionType", + id: id, + completion_data: Object.assign( + {}, + completionData, + // @ts-ignore, weiss oh nöt... + JSON.parse(args.completion_data_string || "{}") + ), + completion_status: args.completion_status, + evaluation_grade: args.evaluation_grade, + evaluation_points: args.evaluation_points, + }, + }; + } + }, + }, + }), + fetchExchange, + ], +}); diff --git a/client/src/graphql/mutations.ts b/client/src/graphql/mutations.ts new file mode 100644 index 00000000..41f07155 --- /dev/null +++ b/client/src/graphql/mutations.ts @@ -0,0 +1,33 @@ +import { graphql } from "@/gql"; + +export const UPSERT_ASSIGNMENT_COMPLETION_MUTATION = graphql(` + mutation UpsertAssignmentCompletion( + $assignmentId: ID! + $courseSessionId: ID! + $assignmentUserId: ID + $completionStatus: String! + $completionDataString: String! + $evaluationGrade: Float + $evaluationPoints: Float + ) { + upsert_assignment_completion( + assignment_id: $assignmentId + course_session_id: $courseSessionId + assignment_user_id: $assignmentUserId + completion_status: $completionStatus + completion_data_string: $completionDataString + evaluation_grade: $evaluationGrade + evaluation_points: $evaluationPoints + ) { + assignment_completion { + id + completion_status + submitted_at + evaluation_submitted_at + evaluation_grade + evaluation_points + completion_data + } + } + } +`); diff --git a/client/src/graphql/queries.ts b/client/src/graphql/queries.ts new file mode 100644 index 00000000..dc57bacd --- /dev/null +++ b/client/src/graphql/queries.ts @@ -0,0 +1,56 @@ +import { graphql } from "@/gql"; + +export const ASSIGNMENT_COMPLETION_QUERY = graphql(` + query assignmentCompletionQuery( + $assignmentId: ID! + $courseSessionId: ID! + $assignmentUserId: ID + ) { + assignment(id: $assignmentId) { + id + content_type + evaluation_description + evaluation_document_url + evaluation_tasks + performance_objectives + starting_position + tasks + title + translation_key + slug + } + assignment_completion( + assignment_id: $assignmentId + course_session_id: $courseSessionId + assignment_user_id: $assignmentUserId + ) { + id + completion_status + submitted_at + evaluation_submitted_at + evaluation_user { + id + } + assignment_user { + id + } + evaluation_grade + evaluation_points + completion_data + } + } +`); + +export const COURSE_QUERY = graphql(` + query courseQuery($courseId: Int!) { + course(id: $courseId) { + id + slug + title + category_name + learning_path { + id + } + } + } +`); diff --git a/client/src/main.ts b/client/src/main.ts index 53e28d85..df15ebee 100644 --- a/client/src/main.ts +++ b/client/src/main.ts @@ -2,16 +2,12 @@ import * as Sentry from "@sentry/vue"; import * as log from "loglevel"; import { createPinia } from "pinia"; import { createApp, markRaw } from "vue"; - -import urql from "@urql/vue"; - +import type { Router } from "vue-router"; +import "../tailwind.css"; import App from "./App.vue"; import { loadLocaleMessages, setupI18n } from "./i18n"; import router from "./router"; -import type { Router } from "vue-router"; -import "../tailwind.css"; - declare module "pinia" { export interface PiniaCustomProperties { router: Router; @@ -50,9 +46,6 @@ loadLocaleMessages("de").then(() => { }); app.use(pinia); app.use(i18n); - app.use(urql, { - url: import.meta.env.VITE_GRAPHQL_URL || "/server/graphql/", - }); app.mount("#app"); }); diff --git a/client/src/pages/cockpit/assignmentEvaluationPage/AssignmentEvaluationPage.vue b/client/src/pages/cockpit/assignmentEvaluationPage/AssignmentEvaluationPage.vue index a887729e..9776cbf9 100644 --- a/client/src/pages/cockpit/assignmentEvaluationPage/AssignmentEvaluationPage.vue +++ b/client/src/pages/cockpit/assignmentEvaluationPage/AssignmentEvaluationPage.vue @@ -1,13 +1,15 @@ diff --git a/client/src/pages/learningPath/learningContentPage/assignment/AssignmentTaskView.vue b/client/src/pages/learningPath/learningContentPage/assignment/AssignmentTaskView.vue index e1cfc704..bf77c787 100644 --- a/client/src/pages/learningPath/learningContentPage/assignment/AssignmentTaskView.vue +++ b/client/src/pages/learningPath/learningContentPage/assignment/AssignmentTaskView.vue @@ -1,30 +1,33 @@ @@ -108,7 +117,7 @@ const completionStatus = computed(() => { value: `confirmation-${index}`, checked: getBlockData(block.id) as boolean, }" - :disabled="completionStatus !== 'in_progress'" + :disabled="completionStatus !== 'IN_PROGRESS'" @toggle="onToggleCheckbox(block.id)" > @@ -122,16 +131,12 @@ const completionStatus = computed(() => { class="w-[300px] sm:w-[600px]" :model-value="(getBlockData(block.id) as string) ?? ''" :cy-key="`user-text-input-${index}`" - :disabled="completionStatus !== 'in_progress'" + :disabled="completionStatus !== 'IN_PROGRESS'" label="" @update:model-value="onUpdateText(block.id, $event)" > - -
- {{ $t("assignment.lastChangesNotSaved") }} -
diff --git a/client/src/pages/learningPath/learningContentPage/assignment/AssignmentView.vue b/client/src/pages/learningPath/learningContentPage/assignment/AssignmentView.vue index 59e40327..79dedb46 100644 --- a/client/src/pages/learningPath/learningContentPage/assignment/AssignmentView.vue +++ b/client/src/pages/learningPath/learningContentPage/assignment/AssignmentView.vue @@ -1,19 +1,22 @@