diff --git a/README.md b/README.md index 68c667d1..5ba494da 100644 --- a/README.md +++ b/README.md @@ -309,3 +309,15 @@ graphql schema. - The `id` field has to be a string? - What about the generated types from `codegen`? Hand written types seem to be better. - The functions in `cacheExchange` should be nearer the concrete implementation... + +## Load prod data for testing + +1. Checkout the [vbv-devops](https://bitbucket.org/iterativ/iterativ-devops/src/master/) repository +2. Change into the `backups` directory +3. Run `python3 check_vbv_backup.py`. This downloads the latest backup from S3 and restores it to the `vbv-lernwelt` database. +4. Reset all user passwords. Open `shell_plus` in the `server` directory of the `vbv_lernwelt` repository and run + + ```python + for csu in CourseSessionUser.objects.all(): + csu.user.set_password("test") + ``` diff --git a/client/package-lock.json b/client/package-lock.json index 78e6e22a..f4917956 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -19,6 +19,7 @@ "@vuepic/vue-datepicker": "^8.8.1", "@vueuse/core": "^10.11.0", "@vueuse/router": "^10.11.0", + "chart.js": "^4.4.4", "cypress": "^12.14.0", "d3": "^7.9.0", "dayjs": "^1.11.11", @@ -32,6 +33,7 @@ "mitt": "^3.0.1", "pinia": "^2.1.7", "vue": "^3.4.31", + "vue-chartjs": "^5.3.1", "vue-router": "^4.4.0" }, "devDependencies": { @@ -2969,6 +2971,11 @@ "integrity": "sha512-4M/Mb2CxzuI1CtQhVFs6OC9ceuGPAP6SOWnpLcrdB1TcUHroXbsYDVJNOm32koRMfuCoRACbojcm4dPPcQxu0w==", "dev": true }, + "node_modules/@kurkle/color": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.2.tgz", + "integrity": "sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw==" + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -6001,6 +6008,17 @@ "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", "dev": true }, + "node_modules/chart.js": { + "version": "4.4.4", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.4.tgz", + "integrity": "sha512-emICKGBABnxhMjUjlYRR12PmOXhJ2eJjEHL2/dZlWjxRAZT1D8xplLFq5M0tMQK8ja+wBS/tuVEJB5C6r7VxJA==", + "dependencies": { + "@kurkle/color": "^0.3.0" + }, + "engines": { + "pnpm": ">=8" + } + }, "node_modules/check-error": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", @@ -14249,6 +14267,15 @@ } } }, + "node_modules/vue-chartjs": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/vue-chartjs/-/vue-chartjs-5.3.1.tgz", + "integrity": "sha512-rZjqcHBxKiHrBl0CIvcOlVEBwRhpWAVf6rDU3vUfa7HuSRmGtCslc0Oc8m16oAVuk0erzc1FCtH1VCriHsrz+A==", + "peerDependencies": { + "chart.js": "^4.1.1", + "vue": "^3.0.0-0 || ^2.7.0" + } + }, "node_modules/vue-component-type-helpers": { "version": "2.0.26", "resolved": "https://registry.npmjs.org/vue-component-type-helpers/-/vue-component-type-helpers-2.0.26.tgz", @@ -16854,6 +16881,11 @@ "integrity": "sha512-4M/Mb2CxzuI1CtQhVFs6OC9ceuGPAP6SOWnpLcrdB1TcUHroXbsYDVJNOm32koRMfuCoRACbojcm4dPPcQxu0w==", "dev": true }, + "@kurkle/color": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.2.tgz", + "integrity": "sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw==" + }, "@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -18998,6 +19030,14 @@ "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", "dev": true }, + "chart.js": { + "version": "4.4.4", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.4.tgz", + "integrity": "sha512-emICKGBABnxhMjUjlYRR12PmOXhJ2eJjEHL2/dZlWjxRAZT1D8xplLFq5M0tMQK8ja+wBS/tuVEJB5C6r7VxJA==", + "requires": { + "@kurkle/color": "^0.3.0" + } + }, "check-error": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", @@ -24648,6 +24688,11 @@ "@vue/shared": "3.4.31" } }, + "vue-chartjs": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/vue-chartjs/-/vue-chartjs-5.3.1.tgz", + "integrity": "sha512-rZjqcHBxKiHrBl0CIvcOlVEBwRhpWAVf6rDU3vUfa7HuSRmGtCslc0Oc8m16oAVuk0erzc1FCtH1VCriHsrz+A==" + }, "vue-component-type-helpers": { "version": "2.0.26", "resolved": "https://registry.npmjs.org/vue-component-type-helpers/-/vue-component-type-helpers-2.0.26.tgz", diff --git a/client/package.json b/client/package.json index f5296e99..9c2813cf 100644 --- a/client/package.json +++ b/client/package.json @@ -30,6 +30,7 @@ "@vuepic/vue-datepicker": "^8.8.1", "@vueuse/core": "^10.11.0", "@vueuse/router": "^10.11.0", + "chart.js": "^4.4.4", "cypress": "^12.14.0", "d3": "^7.9.0", "dayjs": "^1.11.11", @@ -43,6 +44,7 @@ "mitt": "^3.0.1", "pinia": "^2.1.7", "vue": "^3.4.31", + "vue-chartjs": "^5.3.1", "vue-router": "^4.4.0" }, "devDependencies": { diff --git a/client/src/components/dashboard/AttendancePerChosenProfileChart.vue b/client/src/components/dashboard/AttendancePerChosenProfileChart.vue new file mode 100644 index 00000000..a5a687af --- /dev/null +++ b/client/src/components/dashboard/AttendancePerChosenProfileChart.vue @@ -0,0 +1,58 @@ + +w + diff --git a/client/src/components/dashboard/CoursePanel.vue b/client/src/components/dashboard/CoursePanel.vue index b73210f3..89a3a335 100644 --- a/client/src/components/dashboard/CoursePanel.vue +++ b/client/src/components/dashboard/CoursePanel.vue @@ -10,6 +10,7 @@ import LearningPathDiagram from "@/components/learningPath/LearningPathDiagram.v import type { DashboardCourseConfigType, WidgetType } from "@/services/dashboard"; import { getCockpitUrl, getLearningMentorUrl, getLearningPathUrl } from "@/utils/utils"; import { computed } from "vue"; +import TrainingResponsibleStatistics from "./TrainingResponsibleStatistics.vue"; const mentorWidgets = [ "MentorTasksWidget", @@ -71,6 +72,13 @@ const actionButtonProps = computed<{ href: string; text: string; cyKey: string } cyKey: "progress-dashboard-continue-course-link", }; } + if (props.courseConfig?.role_key === "Ausbildungsverantwortlicher") { + return { + href: getLearningPathUrl(props.courseConfig?.course_slug), + text: "a.Vorschau Teilnehmer", + cyKey: "tr-dashboard-link", + }; + } return { href: getLearningPathUrl(props.courseConfig?.course_slug), text: "Weiter lernen", @@ -193,6 +201,12 @@ function hasActionButton(): boolean { :agent-role="courseConfig.role_key" /> + + diff --git a/client/src/components/dashboard/TrainingResponsibleStatistics.vue b/client/src/components/dashboard/TrainingResponsibleStatistics.vue new file mode 100644 index 00000000..8d41383e --- /dev/null +++ b/client/src/components/dashboard/TrainingResponsibleStatistics.vue @@ -0,0 +1,108 @@ + + + diff --git a/client/src/components/dashboard/composables.ts b/client/src/components/dashboard/composables.ts new file mode 100644 index 00000000..a1559b5f --- /dev/null +++ b/client/src/components/dashboard/composables.ts @@ -0,0 +1,25 @@ +import colors from "@/colors.json"; +import { useTranslation } from "i18next-vue"; + +export function useChosenProfileMapping() { + const { t } = useTranslation(); + + const CHOSEN_PROFILE_TO_NAME: Record = { + all: t("a.Allbranche"), + leben: t("a.Leben"), + nichtleben: t("a.Nichtleben"), + krankenzusatzversicherung: t("a.Krankenzusatzversicherung"), + }; + + const CHOSEN_PROFILE_TO_COLOR: Record = { + all: colors.blue[500], + leben: colors.orange[500], + nichtleben: colors.green[500], + krankenzusatzversicherung: colors.yellow[400], + }; + + return { + CHOSEN_PROFILE_TO_NAME, + CHOSEN_PROFILE_TO_COLOR, + }; +} diff --git a/client/src/gql/gql.ts b/client/src/gql/gql.ts index 065feb95..b9c76014 100644 --- a/client/src/gql/gql.ts +++ b/client/src/gql/gql.ts @@ -28,6 +28,7 @@ const documents = { "\n query dashboardCourseData($courseId: ID!) {\n course_progress(course_id: $courseId) {\n _id\n course_id\n session_to_continue_id\n }\n }\n": types.DashboardCourseDataDocument, "\n query courseStatistics($courseId: ID!) {\n course_statistics(course_id: $courseId) {\n _id\n course_id\n course_title\n course_slug\n course_session_properties {\n _id\n sessions {\n id\n name\n region\n }\n generations\n circles {\n id\n name\n }\n }\n course_session_selection_ids\n course_session_selection_metrics {\n _id\n session_count\n participant_count\n expert_count\n }\n attendance_day_presences {\n _id\n records {\n _id\n course_session_id\n generation\n region\n circle_id\n due_date\n participants_present\n participants_total\n details_url\n }\n summary {\n _id\n days_completed\n participants_present\n }\n }\n feedback_responses {\n _id\n records {\n _id\n course_session_id\n generation\n region\n circle_id\n experts\n satisfaction_average\n satisfaction_max\n details_url\n }\n summary {\n _id\n satisfaction_average\n satisfaction_max\n total_responses\n }\n }\n assignments {\n _id\n summary {\n _id\n completed_count\n average_passed\n total_passed\n total_failed\n }\n records {\n _id\n course_session_id\n course_session_assignment_id\n circle_id\n generation\n region\n assignment_title\n assignment_type_translation_key\n competence_certificate_title\n competence_certificate_id\n details_url\n deadline\n metrics {\n _id\n passed_count\n failed_count\n unranked_count\n ranking_completed\n average_evaluation_percent\n average_passed\n competence_certificate_weight\n }\n }\n }\n competences {\n _id\n summary {\n _id\n success_total\n fail_total\n }\n records {\n _id\n course_session_id\n generation\n region\n circle_id\n title\n success_count\n fail_count\n details_url\n }\n }\n }\n }\n": types.CourseStatisticsDocument, "\n query mentorCourseStatistics($courseId: ID!, $agentRole: String!) {\n mentor_course_statistics(course_id: $courseId, agent_role: $agentRole) {\n _id\n course_id\n course_title\n course_slug\n course_session_selection_ids\n user_selection_ids\n course_session_properties {\n _id\n sessions {\n id\n name\n region\n }\n generations\n circles {\n id\n name\n }\n }\n assignments {\n _id\n summary {\n _id\n completed_count\n average_passed\n total_passed\n total_failed\n average_evaluation_percent\n }\n records {\n _id\n course_session_id\n course_session_assignment_id\n course_session_title\n circle_id\n generation\n region\n assignment_title\n assignment_type_translation_key\n competence_certificate_id\n competence_certificate_title\n details_url\n learning_content_id\n deadline\n metrics {\n _id\n passed_count\n failed_count\n unranked_count\n ranking_completed\n competence_certificate_weight\n average_evaluation_percent\n average_passed\n }\n }\n }\n }\n }\n": types.MentorCourseStatisticsDocument, + "\n query trainingResponsibleStatistics($courseSessionId: ID!) {\n training_responsible_statistics(course_session_id: $courseSessionId) {\n _id\n cost_per_year {\n _id\n year\n total_cost\n }\n participants_per_year {\n _id\n year\n participants {\n id\n chosen_profile\n }\n }\n }\n }\n": types.TrainingResponsibleStatisticsDocument, "\n mutation SendFeedbackMutation(\n $courseSessionId: ID!\n $learningContentId: ID!\n $learningContentType: String!\n $data: GenericScalar!\n $submitted: Boolean\n ) {\n send_feedback(\n course_session_id: $courseSessionId\n learning_content_page_id: $learningContentId\n learning_content_type: $learningContentType\n data: $data\n submitted: $submitted\n ) {\n feedback_response {\n id\n data\n submitted\n }\n errors {\n field\n messages\n }\n }\n }\n": types.SendFeedbackMutationDocument, }; @@ -105,6 +106,10 @@ export function graphql(source: "\n query courseStatistics($courseId: 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 query mentorCourseStatistics($courseId: ID!, $agentRole: String!) {\n mentor_course_statistics(course_id: $courseId, agent_role: $agentRole) {\n _id\n course_id\n course_title\n course_slug\n course_session_selection_ids\n user_selection_ids\n course_session_properties {\n _id\n sessions {\n id\n name\n region\n }\n generations\n circles {\n id\n name\n }\n }\n assignments {\n _id\n summary {\n _id\n completed_count\n average_passed\n total_passed\n total_failed\n average_evaluation_percent\n }\n records {\n _id\n course_session_id\n course_session_assignment_id\n course_session_title\n circle_id\n generation\n region\n assignment_title\n assignment_type_translation_key\n competence_certificate_id\n competence_certificate_title\n details_url\n learning_content_id\n deadline\n metrics {\n _id\n passed_count\n failed_count\n unranked_count\n ranking_completed\n competence_certificate_weight\n average_evaluation_percent\n average_passed\n }\n }\n }\n }\n }\n"): (typeof documents)["\n query mentorCourseStatistics($courseId: ID!, $agentRole: String!) {\n mentor_course_statistics(course_id: $courseId, agent_role: $agentRole) {\n _id\n course_id\n course_title\n course_slug\n course_session_selection_ids\n user_selection_ids\n course_session_properties {\n _id\n sessions {\n id\n name\n region\n }\n generations\n circles {\n id\n name\n }\n }\n assignments {\n _id\n summary {\n _id\n completed_count\n average_passed\n total_passed\n total_failed\n average_evaluation_percent\n }\n records {\n _id\n course_session_id\n course_session_assignment_id\n course_session_title\n circle_id\n generation\n region\n assignment_title\n assignment_type_translation_key\n competence_certificate_id\n competence_certificate_title\n details_url\n learning_content_id\n deadline\n metrics {\n _id\n passed_count\n failed_count\n unranked_count\n ranking_completed\n competence_certificate_weight\n average_evaluation_percent\n average_passed\n }\n }\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 trainingResponsibleStatistics($courseSessionId: ID!) {\n training_responsible_statistics(course_session_id: $courseSessionId) {\n _id\n cost_per_year {\n _id\n year\n total_cost\n }\n participants_per_year {\n _id\n year\n participants {\n id\n chosen_profile\n }\n }\n }\n }\n"): (typeof documents)["\n query trainingResponsibleStatistics($courseSessionId: ID!) {\n training_responsible_statistics(course_session_id: $courseSessionId) {\n _id\n cost_per_year {\n _id\n year\n total_cost\n }\n participants_per_year {\n _id\n year\n participants {\n id\n chosen_profile\n }\n }\n }\n }\n"]; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ diff --git a/client/src/gql/graphql.ts b/client/src/gql/graphql.ts index 5f3d2297..c3578130 100644 --- a/client/src/gql/graphql.ts +++ b/client/src/gql/graphql.ts @@ -991,6 +991,7 @@ export type Query = { learning_content_video?: Maybe; learning_path?: Maybe; mentor_course_statistics?: Maybe; + training_responsible_statistics?: Maybe; }; @@ -1063,6 +1064,11 @@ export type QueryMentorCourseStatisticsArgs = { course_id: Scalars['ID']['input']; }; + +export type QueryTrainingResponsibleStatisticsArgs = { + course_session_id: Scalars['ID']['input']; +}; + export type SendFeedbackMutation = { __typename?: 'SendFeedbackMutation'; /** May contain more than one error for same field. */ @@ -1113,6 +1119,28 @@ export type TopicObjectType = CoursePageInterface & { translation_key: Scalars['String']['output']; }; +export type TrainingResponsibleStatisticsType = { + __typename?: 'TrainingResponsibleStatisticsType'; + _id: Scalars['ID']['output']; + cost_per_year: Array>; + course_session_id: Scalars['ID']['output']; + participants_per_year: Array>; +}; + +export type TrainingsResponsibleCostForYear = { + __typename?: 'TrainingsResponsibleCostForYear'; + _id: Scalars['ID']['output']; + total_cost: Scalars['Int']['output']; + year: Scalars['Int']['output']; +}; + +export type TrainingsResponsibleParticipantsForYear = { + __typename?: 'TrainingsResponsibleParticipantsForYear'; + _id: Scalars['ID']['output']; + participants: Array>; + year: Scalars['Int']['output']; +}; + export type UpdateCourseProfileError = { __typename?: 'UpdateCourseProfileError'; message?: Maybe; @@ -1456,6 +1484,13 @@ export type MentorCourseStatisticsQueryVariables = Exact<{ export type MentorCourseStatisticsQuery = { __typename?: 'Query', mentor_course_statistics?: { __typename?: 'BaseStatisticsType', _id: string, course_id: string, course_title: string, course_slug: string, course_session_selection_ids: Array, user_selection_ids?: Array | null, course_session_properties: { __typename?: 'StatisticsCourseSessionPropertiesType', _id: string, generations: Array, sessions: Array<{ __typename?: 'StatisticsCourseSessionDataType', id: string, name: string, region: string }>, circles: Array<{ __typename?: 'StatisticsCircleDataType', id: string, name: string }> }, assignments: { __typename?: 'AssignmentsStatisticsType', _id: string, summary: { __typename?: 'AssignmentStatisticsSummaryType', _id: string, completed_count: number, average_passed: number, total_passed: number, total_failed: number, average_evaluation_percent?: number | null }, records: Array<{ __typename?: 'AssignmentStatisticsRecordType', _id: string, course_session_id: string, course_session_assignment_id: string, course_session_title?: string | null, circle_id: string, generation: string, region: string, assignment_title: string, assignment_type_translation_key: string, competence_certificate_id?: string | null, competence_certificate_title?: string | null, details_url: string, learning_content_id: string, deadline: string, metrics: { __typename?: 'AssignmentCompletionMetricsType', _id: string, passed_count: number, failed_count: number, unranked_count: number, ranking_completed: boolean, competence_certificate_weight?: number | null, average_evaluation_percent?: number | null, average_passed: number } }> } } | null }; +export type TrainingResponsibleStatisticsQueryVariables = Exact<{ + courseSessionId: Scalars['ID']['input']; +}>; + + +export type TrainingResponsibleStatisticsQuery = { __typename?: 'Query', training_responsible_statistics?: { __typename?: 'TrainingResponsibleStatisticsType', _id: string, cost_per_year: Array<{ __typename?: 'TrainingsResponsibleCostForYear', _id: string, year: number, total_cost: number } | null>, participants_per_year: Array<{ __typename?: 'TrainingsResponsibleParticipantsForYear', _id: string, year: number, participants: Array<{ __typename?: 'CourseSessionUserType', id: string, chosen_profile: string } | null> } | null> } | null }; + export type SendFeedbackMutationMutationVariables = Exact<{ courseSessionId: Scalars['ID']['input']; learningContentId: Scalars['ID']['input']; @@ -1482,4 +1517,5 @@ export const DashboardProgressDocument = {"kind":"Document","definitions":[{"kin export const DashboardCourseDataDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"dashboardCourseData"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"courseId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"course_progress"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"course_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":"course_id"}},{"kind":"Field","name":{"kind":"Name","value":"session_to_continue_id"}}]}}]}}]} as unknown as DocumentNode; export const CourseStatisticsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"courseStatistics"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"courseId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"course_statistics"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"course_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":"course_id"}},{"kind":"Field","name":{"kind":"Name","value":"course_title"}},{"kind":"Field","name":{"kind":"Name","value":"course_slug"}},{"kind":"Field","name":{"kind":"Name","value":"course_session_properties"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"sessions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"region"}}]}},{"kind":"Field","name":{"kind":"Name","value":"generations"}},{"kind":"Field","name":{"kind":"Name","value":"circles"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"course_session_selection_ids"}},{"kind":"Field","name":{"kind":"Name","value":"course_session_selection_metrics"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"session_count"}},{"kind":"Field","name":{"kind":"Name","value":"participant_count"}},{"kind":"Field","name":{"kind":"Name","value":"expert_count"}}]}},{"kind":"Field","name":{"kind":"Name","value":"attendance_day_presences"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"records"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"course_session_id"}},{"kind":"Field","name":{"kind":"Name","value":"generation"}},{"kind":"Field","name":{"kind":"Name","value":"region"}},{"kind":"Field","name":{"kind":"Name","value":"circle_id"}},{"kind":"Field","name":{"kind":"Name","value":"due_date"}},{"kind":"Field","name":{"kind":"Name","value":"participants_present"}},{"kind":"Field","name":{"kind":"Name","value":"participants_total"}},{"kind":"Field","name":{"kind":"Name","value":"details_url"}}]}},{"kind":"Field","name":{"kind":"Name","value":"summary"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"days_completed"}},{"kind":"Field","name":{"kind":"Name","value":"participants_present"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"feedback_responses"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"records"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"course_session_id"}},{"kind":"Field","name":{"kind":"Name","value":"generation"}},{"kind":"Field","name":{"kind":"Name","value":"region"}},{"kind":"Field","name":{"kind":"Name","value":"circle_id"}},{"kind":"Field","name":{"kind":"Name","value":"experts"}},{"kind":"Field","name":{"kind":"Name","value":"satisfaction_average"}},{"kind":"Field","name":{"kind":"Name","value":"satisfaction_max"}},{"kind":"Field","name":{"kind":"Name","value":"details_url"}}]}},{"kind":"Field","name":{"kind":"Name","value":"summary"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"satisfaction_average"}},{"kind":"Field","name":{"kind":"Name","value":"satisfaction_max"}},{"kind":"Field","name":{"kind":"Name","value":"total_responses"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"assignments"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"summary"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"completed_count"}},{"kind":"Field","name":{"kind":"Name","value":"average_passed"}},{"kind":"Field","name":{"kind":"Name","value":"total_passed"}},{"kind":"Field","name":{"kind":"Name","value":"total_failed"}}]}},{"kind":"Field","name":{"kind":"Name","value":"records"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"course_session_id"}},{"kind":"Field","name":{"kind":"Name","value":"course_session_assignment_id"}},{"kind":"Field","name":{"kind":"Name","value":"circle_id"}},{"kind":"Field","name":{"kind":"Name","value":"generation"}},{"kind":"Field","name":{"kind":"Name","value":"region"}},{"kind":"Field","name":{"kind":"Name","value":"assignment_title"}},{"kind":"Field","name":{"kind":"Name","value":"assignment_type_translation_key"}},{"kind":"Field","name":{"kind":"Name","value":"competence_certificate_title"}},{"kind":"Field","name":{"kind":"Name","value":"competence_certificate_id"}},{"kind":"Field","name":{"kind":"Name","value":"details_url"}},{"kind":"Field","name":{"kind":"Name","value":"deadline"}},{"kind":"Field","name":{"kind":"Name","value":"metrics"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"passed_count"}},{"kind":"Field","name":{"kind":"Name","value":"failed_count"}},{"kind":"Field","name":{"kind":"Name","value":"unranked_count"}},{"kind":"Field","name":{"kind":"Name","value":"ranking_completed"}},{"kind":"Field","name":{"kind":"Name","value":"average_evaluation_percent"}},{"kind":"Field","name":{"kind":"Name","value":"average_passed"}},{"kind":"Field","name":{"kind":"Name","value":"competence_certificate_weight"}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"competences"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"summary"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"success_total"}},{"kind":"Field","name":{"kind":"Name","value":"fail_total"}}]}},{"kind":"Field","name":{"kind":"Name","value":"records"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"course_session_id"}},{"kind":"Field","name":{"kind":"Name","value":"generation"}},{"kind":"Field","name":{"kind":"Name","value":"region"}},{"kind":"Field","name":{"kind":"Name","value":"circle_id"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"success_count"}},{"kind":"Field","name":{"kind":"Name","value":"fail_count"}},{"kind":"Field","name":{"kind":"Name","value":"details_url"}}]}}]}}]}}]}}]} as unknown as DocumentNode; export const MentorCourseStatisticsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"mentorCourseStatistics"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"courseId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"agentRole"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"mentor_course_statistics"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"course_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"courseId"}}},{"kind":"Argument","name":{"kind":"Name","value":"agent_role"},"value":{"kind":"Variable","name":{"kind":"Name","value":"agentRole"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"course_id"}},{"kind":"Field","name":{"kind":"Name","value":"course_title"}},{"kind":"Field","name":{"kind":"Name","value":"course_slug"}},{"kind":"Field","name":{"kind":"Name","value":"course_session_selection_ids"}},{"kind":"Field","name":{"kind":"Name","value":"user_selection_ids"}},{"kind":"Field","name":{"kind":"Name","value":"course_session_properties"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"sessions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"region"}}]}},{"kind":"Field","name":{"kind":"Name","value":"generations"}},{"kind":"Field","name":{"kind":"Name","value":"circles"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"assignments"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"summary"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"completed_count"}},{"kind":"Field","name":{"kind":"Name","value":"average_passed"}},{"kind":"Field","name":{"kind":"Name","value":"total_passed"}},{"kind":"Field","name":{"kind":"Name","value":"total_failed"}},{"kind":"Field","name":{"kind":"Name","value":"average_evaluation_percent"}}]}},{"kind":"Field","name":{"kind":"Name","value":"records"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"course_session_id"}},{"kind":"Field","name":{"kind":"Name","value":"course_session_assignment_id"}},{"kind":"Field","name":{"kind":"Name","value":"course_session_title"}},{"kind":"Field","name":{"kind":"Name","value":"circle_id"}},{"kind":"Field","name":{"kind":"Name","value":"generation"}},{"kind":"Field","name":{"kind":"Name","value":"region"}},{"kind":"Field","name":{"kind":"Name","value":"assignment_title"}},{"kind":"Field","name":{"kind":"Name","value":"assignment_type_translation_key"}},{"kind":"Field","name":{"kind":"Name","value":"competence_certificate_id"}},{"kind":"Field","name":{"kind":"Name","value":"competence_certificate_title"}},{"kind":"Field","name":{"kind":"Name","value":"details_url"}},{"kind":"Field","name":{"kind":"Name","value":"learning_content_id"}},{"kind":"Field","name":{"kind":"Name","value":"deadline"}},{"kind":"Field","name":{"kind":"Name","value":"metrics"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"passed_count"}},{"kind":"Field","name":{"kind":"Name","value":"failed_count"}},{"kind":"Field","name":{"kind":"Name","value":"unranked_count"}},{"kind":"Field","name":{"kind":"Name","value":"ranking_completed"}},{"kind":"Field","name":{"kind":"Name","value":"competence_certificate_weight"}},{"kind":"Field","name":{"kind":"Name","value":"average_evaluation_percent"}},{"kind":"Field","name":{"kind":"Name","value":"average_passed"}}]}}]}}]}}]}}]}}]} as unknown as DocumentNode; +export const TrainingResponsibleStatisticsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"trainingResponsibleStatistics"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"training_responsible_statistics"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"course_session_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"cost_per_year"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"year"}},{"kind":"Field","name":{"kind":"Name","value":"total_cost"}}]}},{"kind":"Field","name":{"kind":"Name","value":"participants_per_year"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"year"}},{"kind":"Field","name":{"kind":"Name","value":"participants"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"chosen_profile"}}]}}]}}]}}]}}]} as unknown as DocumentNode; 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":"courseSessionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"learningContentId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"learningContentType"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"data"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"GenericScalar"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"submitted"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"send_feedback"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"course_session_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"courseSessionId"}}},{"kind":"Argument","name":{"kind":"Name","value":"learning_content_page_id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"learningContentId"}}},{"kind":"Argument","name":{"kind":"Name","value":"learning_content_type"},"value":{"kind":"Variable","name":{"kind":"Name","value":"learningContentType"}}},{"kind":"Argument","name":{"kind":"Name","value":"data"},"value":{"kind":"Variable","name":{"kind":"Name","value":"data"}}},{"kind":"Argument","name":{"kind":"Name","value":"submitted"},"value":{"kind":"Variable","name":{"kind":"Name","value":"submitted"}}}],"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":"data"}},{"kind":"Field","name":{"kind":"Name","value":"submitted"}}]}},{"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; \ No newline at end of file diff --git a/client/src/gql/schema.graphql b/client/src/gql/schema.graphql index 1c644eb4..49bdd135 100644 --- a/client/src/gql/schema.graphql +++ b/client/src/gql/schema.graphql @@ -1,6 +1,7 @@ type Query { course_statistics(course_id: ID!): CourseStatisticsType mentor_course_statistics(course_id: ID!, agent_role: String!): BaseStatisticsType + training_responsible_statistics(course_session_id: ID!): TrainingResponsibleStatisticsType course_progress(course_id: ID!): CourseProgressType dashboard_config: [DashboardConfigType!]! learning_path(id: ID, slug: String, course_id: ID, course_slug: String): LearningPathObjectType @@ -200,42 +201,61 @@ type BaseStatisticsType { course_session_properties: StatisticsCourseSessionPropertiesType! } -type CourseProgressType { +type TrainingResponsibleStatisticsType { _id: ID! - course_id: ID! - session_to_continue_id: ID - competence: ProgressDashboardCompetenceType - assignment: ProgressDashboardAssignmentType + course_session_id: ID! + cost_per_year: [TrainingsResponsibleCostForYear]! + participants_per_year: [TrainingsResponsibleParticipantsForYear]! } -type ProgressDashboardCompetenceType { +type TrainingsResponsibleCostForYear { _id: ID! - total_count: Int! - success_count: Int! - fail_count: Int! + year: Int! + total_cost: Int! } -type ProgressDashboardAssignmentType { +type TrainingsResponsibleParticipantsForYear { _id: ID! - total_count: Int! - points_max_count: Int! - points_achieved_count: Int! + year: Int! + participants: [CourseSessionUserType]! } -type DashboardConfigType { +type CourseSessionUserType { + id: UUID! + chosen_profile: String! + course_session: CourseSessionObjectType! +} + +""" +Leverages the internal Python implementation of UUID (uuid.UUID) to provide native UUID objects +in fields, resolvers and input. +""" +scalar UUID + +type CourseSessionObjectType { id: ID! - name: String! - slug: String! - dashboard_type: DashboardType! - course_configuration: CourseConfigurationObjectType! + created_at: DateTime! + updated_at: DateTime! + course: CourseObjectType! + title: String! + start_date: Date + end_date: Date + attendance_courses: [CourseSessionAttendanceCourseObjectType!]! + assignments: [CourseSessionAssignmentObjectType!]! + edoniq_tests: [CourseSessionEdoniqTestObjectType!]! + users: [CourseSessionUserObjectsType!]! } -enum DashboardType { - STATISTICS_DASHBOARD - PROGRESS_DASHBOARD - SIMPLE_DASHBOARD - MENTOR_DASHBOARD - PRAXISBILDNER_DASHBOARD +type CourseObjectType { + id: ID! + title: String! + category_name: String! + slug: String! + configuration: CourseConfigurationObjectType! + learning_path: LearningPathObjectType! + action_competences: [ActionCompetenceObjectType!]! + profiles: [String] + course_session_users(id: String): [CourseSessionUserType]! } type CourseConfigurationObjectType { @@ -270,20 +290,8 @@ interface CoursePageInterface { course: CourseObjectType } -type CourseObjectType { - id: ID! - title: String! - category_name: String! - slug: String! - configuration: CourseConfigurationObjectType! - learning_path: LearningPathObjectType! - action_competences: [ActionCompetenceObjectType!]! - profiles: [String] - course_session_users(id: String): [CourseSessionUserType]! -} - -type ActionCompetenceObjectType implements CoursePageInterface { - competence_id: String! +type TopicObjectType implements CoursePageInterface { + is_visible: Boolean! id: ID! title: String! slug: String! @@ -292,11 +300,13 @@ type ActionCompetenceObjectType implements CoursePageInterface { translation_key: String! frontend_url: String! course: CourseObjectType - performance_criteria: [PerformanceCriteriaObjectType!]! + circles: [CircleObjectType!]! } -type PerformanceCriteriaObjectType implements CoursePageInterface { - competence_id: String! +type CircleObjectType implements CoursePageInterface { + description: String! + goals: String! + is_base_circle: Boolean! id: ID! title: String! slug: String! @@ -305,7 +315,21 @@ type PerformanceCriteriaObjectType implements CoursePageInterface { translation_key: String! frontend_url: String! course: CourseObjectType - learning_unit: LearningUnitObjectType + learning_sequences: [LearningSequenceObjectType!]! + profiles: [String]! +} + +type LearningSequenceObjectType implements CoursePageInterface { + icon: String! + id: ID! + title: String! + slug: String! + content_type: String! + live: Boolean! + translation_key: String! + frontend_url: String! + course: CourseObjectType + learning_units: [LearningUnitObjectType!]! } type LearningUnitObjectType implements CoursePageInterface { @@ -345,30 +369,30 @@ type CircleLightObjectType { slug: String! } -type CourseSessionUserType { - id: UUID! - chosen_profile: String! - course_session: CourseSessionObjectType! +type PerformanceCriteriaObjectType implements CoursePageInterface { + competence_id: String! + id: ID! + title: String! + slug: String! + content_type: String! + live: Boolean! + translation_key: String! + frontend_url: String! + course: CourseObjectType + learning_unit: LearningUnitObjectType } -""" -Leverages the internal Python implementation of UUID (uuid.UUID) to provide native UUID objects -in fields, resolvers and input. -""" -scalar UUID - -type CourseSessionObjectType { +type ActionCompetenceObjectType implements CoursePageInterface { + competence_id: String! id: ID! - created_at: DateTime! - updated_at: DateTime! - course: CourseObjectType! title: String! - start_date: Date - end_date: Date - attendance_courses: [CourseSessionAttendanceCourseObjectType!]! - assignments: [CourseSessionAssignmentObjectType!]! - edoniq_tests: [CourseSessionEdoniqTestObjectType!]! - users: [CourseSessionUserObjectsType!]! + slug: String! + content_type: String! + live: Boolean! + translation_key: String! + frontend_url: String! + course: CourseObjectType + performance_criteria: [PerformanceCriteriaObjectType!]! } """ @@ -717,46 +741,42 @@ type CourseSessionUserExpertCircleType { slug: String! } -type TopicObjectType implements CoursePageInterface { - is_visible: Boolean! - id: ID! - title: String! - slug: String! - content_type: String! - live: Boolean! - translation_key: String! - frontend_url: String! - course: CourseObjectType - circles: [CircleObjectType!]! +type CourseProgressType { + _id: ID! + course_id: ID! + session_to_continue_id: ID + competence: ProgressDashboardCompetenceType + assignment: ProgressDashboardAssignmentType } -type CircleObjectType implements CoursePageInterface { - description: String! - goals: String! - is_base_circle: Boolean! - id: ID! - title: String! - slug: String! - content_type: String! - live: Boolean! - translation_key: String! - frontend_url: String! - course: CourseObjectType - learning_sequences: [LearningSequenceObjectType!]! - profiles: [String]! +type ProgressDashboardCompetenceType { + _id: ID! + total_count: Int! + success_count: Int! + fail_count: Int! } -type LearningSequenceObjectType implements CoursePageInterface { - icon: String! +type ProgressDashboardAssignmentType { + _id: ID! + total_count: Int! + points_max_count: Int! + points_achieved_count: Int! +} + +type DashboardConfigType { id: ID! - title: String! + name: String! slug: String! - content_type: String! - live: Boolean! - translation_key: String! - frontend_url: String! - course: CourseObjectType - learning_units: [LearningUnitObjectType!]! + dashboard_type: DashboardType! + course_configuration: CourseConfigurationObjectType! +} + +enum DashboardType { + STATISTICS_DASHBOARD + PROGRESS_DASHBOARD + SIMPLE_DASHBOARD + MENTOR_DASHBOARD + PRAXISBILDNER_DASHBOARD } type LearningContentMediaLibraryObjectType implements CoursePageInterface & LearningContentInterface { diff --git a/client/src/gql/typenames.ts b/client/src/gql/typenames.ts index c6712dfd..382132b8 100644 --- a/client/src/gql/typenames.ts +++ b/client/src/gql/typenames.ts @@ -86,6 +86,9 @@ export const StatisticsCourseSessionPropertiesType = "StatisticsCourseSessionPro export const StatisticsCourseSessionsSelectionMetricType = "StatisticsCourseSessionsSelectionMetricType"; export const String = "String"; export const TopicObjectType = "TopicObjectType"; +export const TrainingResponsibleStatisticsType = "TrainingResponsibleStatisticsType"; +export const TrainingsResponsibleCostForYear = "TrainingsResponsibleCostForYear"; +export const TrainingsResponsibleParticipantsForYear = "TrainingsResponsibleParticipantsForYear"; export const UUID = "UUID"; export const UpdateCourseProfileError = "UpdateCourseProfileError"; export const UpdateCourseProfileResult = "UpdateCourseProfileResult"; diff --git a/client/src/graphql/queries.ts b/client/src/graphql/queries.ts index 8beea4f4..246e060a 100644 --- a/client/src/graphql/queries.ts +++ b/client/src/graphql/queries.ts @@ -607,3 +607,24 @@ export const DASHBOARD_MENTOR_COMPETENCE_SUMMARY = graphql(` } } `); + +export const TRAINING_RESPONSIBLE_STATISTICS = graphql(` + query trainingResponsibleStatistics($courseSessionId: ID!) { + training_responsible_statistics(course_session_id: $courseSessionId) { + _id + cost_per_year { + _id + year + total_cost + } + participants_per_year { + _id + year + participants { + id + chosen_profile + } + } + } + } +`); diff --git a/client/src/pages/dashboard/DashboardCostPage.vue b/client/src/pages/dashboard/DashboardCostPage.vue new file mode 100644 index 00000000..ff9863cb --- /dev/null +++ b/client/src/pages/dashboard/DashboardCostPage.vue @@ -0,0 +1,64 @@ + + + diff --git a/client/src/pages/dashboard/DashboardPersonsPage.vue b/client/src/pages/dashboard/DashboardPersonsPage.vue index 6e89792f..d7c4a149 100644 --- a/client/src/pages/dashboard/DashboardPersonsPage.vue +++ b/client/src/pages/dashboard/DashboardPersonsPage.vue @@ -1,4 +1,5 @@