From 5e0b69702f09da4ef06d2bada9b83f313bc75562 Mon Sep 17 00:00:00 2001 From: Christian Cueni Date: Tue, 13 Dec 2022 08:42:29 +0100 Subject: [PATCH 01/13] Add file upload modal --- client/src/components/MainNavigationBar.vue | 26 +++++----- client/src/locales/de.json | 10 +++- client/src/pages/learningPath/CirclePage.vue | 49 ++++++++++++++++++- .../vbv_lernwelt/core/create_default_users.py | 3 +- 4 files changed, 71 insertions(+), 17 deletions(-) diff --git a/client/src/components/MainNavigationBar.vue b/client/src/components/MainNavigationBar.vue index 80394067..236bbd2f 100644 --- a/client/src/components/MainNavigationBar.vue +++ b/client/src/components/MainNavigationBar.vue @@ -168,6 +168,19 @@ const profileDropdownData: DropdownListItem[] = [ + + {{ $t("cockpit.title") }} + + - - {{ $t("cockpit.title") }} - - (); +const showUploadModal = ref(false); + const appStore = useAppStore(); appStore.showMainNavigationBar = true; @@ -110,7 +114,7 @@ onMounted(async () => { @click="circleStore.page = 'OVERVIEW'" > - Das lernst du in diesem Circle + {{ $t("circlePage.circleContentBoxTitle") }}
@@ -135,8 +139,24 @@ onMounted(async () => {
+
+

+ {{ $t("circlePage.documentsTitle") }} +

+
+ {{ $t("circlePage.documentsDescription") }} +
+ + +
+
-

Hast du Fragen?

+

{{ $t("circlePage.gotQuestions") }}

Tausche dich mit der Fachexpertin aus für den Circle Analyse aus.
@@ -161,6 +181,31 @@ onMounted(async () => {
+ + + + diff --git a/server/vbv_lernwelt/core/create_default_users.py b/server/vbv_lernwelt/core/create_default_users.py index 7cbbee64..861ade66 100644 --- a/server/vbv_lernwelt/core/create_default_users.py +++ b/server/vbv_lernwelt/core/create_default_users.py @@ -122,10 +122,11 @@ def create_default_users(user_model=User, group_model=Group, default_password=No last_name="VV", ) _create_student_user( - email="patrizia.huggel@eiger-versicherung.ch", + email="patrizia.huggel@eiger-versicherungen.ch", first_name="Patrizia", last_name="Huggel", avatar_url="/static/avatars/uk1.patrizia.huggel.jpg", + password="myvbv1234", ) _create_student_user( email="daniel.tanaka@eiger-versicherung.ch", From e8085831dfad68192ce4be107dedf5f4214846bf Mon Sep 17 00:00:00 2001 From: Christian Cueni Date: Tue, 13 Dec 2022 11:21:16 +0100 Subject: [PATCH 02/13] Add learning sequence field --- client/src/locales/de.json | 18 ++++--- client/src/pages/cockpit/CockpitIndexPage.vue | 2 +- client/src/pages/learningPath/CirclePage.vue | 51 +++++++++++++++---- 3 files changed, 53 insertions(+), 18 deletions(-) diff --git a/client/src/locales/de.json b/client/src/locales/de.json index 51b29218..0dd272c8 100644 --- a/client/src/locales/de.json +++ b/client/src/locales/de.json @@ -10,6 +10,7 @@ "save": "Speichern", "learningUnit": "Lerneinheit", "learningPath": "Lernpfad", + "learningSequence": "Lernsequenz", "show": "Anschauen", "circles": "Circles", "transferTask": "Transferauftrag | Transferaufträge", @@ -34,13 +35,16 @@ "duration": "Dauer", "circleContentBoxTitle": "Das lernst du in diesem Circle.", "gotQuestions": "Hast du Fragen?", - "documentsTitle": "Unterlagen", - "documentsDescription": "Stelle deinen Lernenden zusätzliche Inhalte zur Verfügung.", - "documentsAction": "Unterlagen hochladen", - "documentsModalAction": "Datei auswählen", - "documentsModalLabel": "Datei", - "documentsModalFileName": "Name", - "documentsModalNameInformation": "Max. 70 Zeichen" + "documents": { + "title": "Unterlagen", + "description": "Stelle deinen Lernenden zusätzliche Inhalte zur Verfügung.", + "action": "Unterlagen hochladen", + "modalAction": "Datei auswählen", + "fileLabel": "Datei", + "modalFileName": "Name", + "modalNameInformation": "Max. 70 Zeichen", + "chooseSequence": "Wähle eine Lernsequenz aus" + } }, "learningContent": { "completeAndContinue": "Abschliessen und weiter" diff --git a/client/src/pages/cockpit/CockpitIndexPage.vue b/client/src/pages/cockpit/CockpitIndexPage.vue index 9bf737a3..38714db5 100644 --- a/client/src/pages/cockpit/CockpitIndexPage.vue +++ b/client/src/pages/cockpit/CockpitIndexPage.vue @@ -137,7 +137,7 @@ function setActiveCircle(id: number) { diagram-type="horizontalSmall" > -
KMU Teil 1
+
Einstieg
diff --git a/client/src/pages/learningPath/CirclePage.vue b/client/src/pages/learningPath/CirclePage.vue index bb0a2cce..a5e6dcd9 100644 --- a/client/src/pages/learningPath/CirclePage.vue +++ b/client/src/pages/learningPath/CirclePage.vue @@ -2,18 +2,21 @@ import CircleDiagram from "@/components/learningPath/CircleDiagram.vue"; import CircleOverview from "@/components/learningPath/CircleOverview.vue"; import LearningSequence from "@/components/learningPath/LearningSequence.vue"; +import ItDropdownSelect from "@/components/ui/ItDropdownSelect.vue"; import ItModal from "@/components/ui/ItModal.vue"; import * as log from "loglevel"; -import { ref } from "vue"; +import { reactive, ref } from "vue"; import { useAppStore } from "@/stores/app"; import { useCircleStore } from "@/stores/circle"; import { humanizeDuration } from "@/utils/humanizeDuration"; import _ from "lodash"; import { computed, onMounted } from "vue"; +import { useI18n } from "vue-i18n"; import { useRoute } from "vue-router"; const route = useRoute(); +const { t } = useI18n(); log.debug("CircleView.vue created", route); @@ -23,6 +26,14 @@ const props = defineProps<{ }>(); const showUploadModal = ref(false); +const formData = reactive({ + file: "", + name: "", + learningSequence: { + id: -1, + name: t("circlePage.documents.chooseSequence"), + }, +}); const appStore = useAppStore(); appStore.showMainNavigationBar = true; @@ -38,6 +49,13 @@ const duration = computed(() => { return ""; }); +const dropdownLearningSequences = computed(() => + circleStore.circle?.learningSequences.map((sequence) => ({ + id: sequence.id, + name: sequence.title, + })) +); + onMounted(async () => { log.debug("CircleView.vue mounted", props.courseSlug, props.circleSlug); @@ -141,17 +159,17 @@ onMounted(async () => {

- {{ $t("circlePage.documentsTitle") }} + {{ $t("circlePage.documents.title") }}

- {{ $t("circlePage.documentsDescription") }} + {{ $t("circlePage.documents.description") }}
@@ -182,26 +200,39 @@ onMounted(async () => {
- + From 4ac1c78a4f98cb6b49eafbef20e0ceb74b2e1aba Mon Sep 17 00:00:00 2001 From: Christian Cueni Date: Tue, 13 Dec 2022 14:21:26 +0100 Subject: [PATCH 03/13] Update path name --- client/src/components/ui/ItModal.vue | 41 +++++++++++++++++++ client/src/stores/mediaLibrary.ts | 2 +- cypress/e2e/learningPath.cy.js | 2 +- .../creators/versicherungsvermittlerin.py | 2 +- server/vbv_lernwelt/course/factories.py | 4 +- .../commands/create_default_courses.py | 2 +- .../tests/learning_path_factories.py | 2 +- 7 files changed, 48 insertions(+), 7 deletions(-) create mode 100644 client/src/components/ui/ItModal.vue diff --git a/client/src/components/ui/ItModal.vue b/client/src/components/ui/ItModal.vue new file mode 100644 index 00000000..3e1a049d --- /dev/null +++ b/client/src/components/ui/ItModal.vue @@ -0,0 +1,41 @@ + + + diff --git a/client/src/stores/mediaLibrary.ts b/client/src/stores/mediaLibrary.ts index 8eb28034..681fc6a2 100644 --- a/client/src/stores/mediaLibrary.ts +++ b/client/src/stores/mediaLibrary.ts @@ -17,7 +17,7 @@ export const useMediaLibraryStore = defineStore({ selectedLearningPath: { id: 1, name: "Alle Lehrgänge" }, availableLearningPaths: [ { id: 1, name: "Alle Lehrgänge" }, - { id: 2, name: "Versicherungsvermittler/in" }, + { id: 2, name: "Versicherungsvermittler/-in" }, ], } as MediaLibraryStoreState; }, diff --git a/cypress/e2e/learningPath.cy.js b/cypress/e2e/learningPath.cy.js index 47a595ca..38d6c715 100644 --- a/cypress/e2e/learningPath.cy.js +++ b/cypress/e2e/learningPath.cy.js @@ -11,7 +11,7 @@ describe("learningPath page", () => { cy.get('[data-cy="learning-path-title"]').should( "contain", - "Versicherungsvermittler/in" + "Versicherungsvermittler/-in" ); }); diff --git a/server/vbv_lernwelt/course/creators/versicherungsvermittlerin.py b/server/vbv_lernwelt/course/creators/versicherungsvermittlerin.py index 7855bdde..c2f89551 100644 --- a/server/vbv_lernwelt/course/creators/versicherungsvermittlerin.py +++ b/server/vbv_lernwelt/course/creators/versicherungsvermittlerin.py @@ -10,7 +10,7 @@ def create_versicherungsvermittlerin_with_categories( apps=None, schema_editor=None, course_id=COURSE_VERSICHERUNGSVERMITTLERIN_ID, - title="Versicherungsvermittler/in", + title="Versicherungsvermittler/-in", ): if apps is not None: Course = apps.get_model("course", "Course") diff --git a/server/vbv_lernwelt/course/factories.py b/server/vbv_lernwelt/course/factories.py index 2931a070..a6e94a9a 100644 --- a/server/vbv_lernwelt/course/factories.py +++ b/server/vbv_lernwelt/course/factories.py @@ -8,12 +8,12 @@ class CourseFactory(DjangoModelFactory): class Meta: model = Course - title = "Versicherungsvermittler/in" + title = "Versicherungsvermittler/-in" category_name = "Handlungsfeld" class CoursePageFactory(wagtail_factories.PageFactory): - title = "Versicherungsvermittler/in" + title = "Versicherungsvermittler/-in" class Meta: model = CoursePage diff --git a/server/vbv_lernwelt/course/management/commands/create_default_courses.py b/server/vbv_lernwelt/course/management/commands/create_default_courses.py index 488fcb0c..f720a14f 100644 --- a/server/vbv_lernwelt/course/management/commands/create_default_courses.py +++ b/server/vbv_lernwelt/course/management/commands/create_default_courses.py @@ -63,7 +63,7 @@ def command(): # course session Versicherungsvermittler/in cs = CourseSession.objects.create( course_id=COURSE_VERSICHERUNGSVERMITTLERIN_ID, - title="Versicherungsvermittler/in", + title="Versicherungsvermittler/-in", ) for user_data in default_users: CourseSessionUser.objects.create( diff --git a/server/vbv_lernwelt/learnpath/tests/learning_path_factories.py b/server/vbv_lernwelt/learnpath/tests/learning_path_factories.py index fdd9222a..a70de2f5 100644 --- a/server/vbv_lernwelt/learnpath/tests/learning_path_factories.py +++ b/server/vbv_lernwelt/learnpath/tests/learning_path_factories.py @@ -24,7 +24,7 @@ from vbv_lernwelt.learnpath.models_learning_unit_content import ( class LearningPathFactory(wagtail_factories.PageFactory): - title = "Versicherungsvermittler/in" + title = "Versicherungsvermittler/-in" class Meta: model = LearningPath From 786f92595cf40dd1e0b0caca68cf71dfad253402 Mon Sep 17 00:00:00 2001 From: Christian Cueni Date: Tue, 13 Dec 2022 14:29:48 +0100 Subject: [PATCH 04/13] Show upload button only to experts --- client/src/pages/learningPath/CirclePage.vue | 21 +++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/client/src/pages/learningPath/CirclePage.vue b/client/src/pages/learningPath/CirclePage.vue index a5e6dcd9..036d4bf7 100644 --- a/client/src/pages/learningPath/CirclePage.vue +++ b/client/src/pages/learningPath/CirclePage.vue @@ -9,6 +9,7 @@ import { reactive, ref } from "vue"; import { useAppStore } from "@/stores/app"; import { useCircleStore } from "@/stores/circle"; +import { useCourseSessionsStore } from "@/stores/courseSessions"; import { humanizeDuration } from "@/utils/humanizeDuration"; import _ from "lodash"; import { computed, onMounted } from "vue"; @@ -17,6 +18,7 @@ import { useRoute } from "vue-router"; const route = useRoute(); const { t } = useI18n(); +const courseSessionsStore = useCourseSessionsStore(); log.debug("CircleView.vue created", route); @@ -161,16 +163,17 @@ onMounted(async () => {

{{ $t("circlePage.documents.title") }}

-
- {{ $t("circlePage.documents.description") }} +
+
+ {{ $t("circlePage.documents.description") }} +
+
- -
From b950f11942efd08f75c45c4bf6af2b64189442a2 Mon Sep 17 00:00:00 2001 From: Christian Cueni Date: Tue, 13 Dec 2022 20:31:35 +0100 Subject: [PATCH 05/13] Update course slugs --- cypress/e2e/learningPath.cy.js | 2 +- cypress/e2e/login.cy.js | 2 +- .../commands/create_default_courses.py | 6 ++--- .../create_default_media_library.py | 26 +++++++++---------- .../tests/media_library_factories.py | 2 +- 5 files changed, 19 insertions(+), 19 deletions(-) diff --git a/cypress/e2e/learningPath.cy.js b/cypress/e2e/learningPath.cy.js index 38d6c715..6a67d406 100644 --- a/cypress/e2e/learningPath.cy.js +++ b/cypress/e2e/learningPath.cy.js @@ -7,7 +7,7 @@ describe("learningPath page", () => { it("can open learningPath page", () => { login("admin", "test"); - cy.visit("/learn/versicherungsvermittlerin-lp"); + cy.visit("/learn/versicherungsvermittler-in-lp"); cy.get('[data-cy="learning-path-title"]').should( "contain", diff --git a/cypress/e2e/login.cy.js b/cypress/e2e/login.cy.js index 50e2e21c..ea987acb 100644 --- a/cypress/e2e/login.cy.js +++ b/cypress/e2e/login.cy.js @@ -31,7 +31,7 @@ describe("login", () => { }); it("login will redirect to requestet page", () => { - cy.visit("/learn/versicherungsvermittlerin-lp"); + cy.visit("/learn/versicherungsvermittler-in-lp"); cy.get("h1").should("contain", "Login"); cy.get("#username").type("admin"); diff --git a/server/vbv_lernwelt/course/management/commands/create_default_courses.py b/server/vbv_lernwelt/course/management/commands/create_default_courses.py index f720a14f..f82a8504 100644 --- a/server/vbv_lernwelt/course/management/commands/create_default_courses.py +++ b/server/vbv_lernwelt/course/management/commands/create_default_courses.py @@ -80,7 +80,7 @@ def command(): role=CourseSessionUser.Role.EXPERT, ) csu.expert.add( - Circle.objects.get(slug="versicherungsvermittlerin-lp-circle-einstieg") + Circle.objects.get(slug="versicherungsvermittler-in-lp-circle-einstieg") ) csu = CourseSessionUser.objects.create( course_session=cs, @@ -88,7 +88,7 @@ def command(): role=CourseSessionUser.Role.EXPERT, ) csu.expert.add( - Circle.objects.get(slug="versicherungsvermittlerin-lp-circle-analyse") + Circle.objects.get(slug="versicherungsvermittler-in-lp-circle-analyse") ) # course session Überbetriebliche Kurse Lehrjahr 1 - Region Bern @@ -119,7 +119,7 @@ def command(): # figma demo users and data csu = CourseSessionUser.objects.create( course_session=cs, - user=User.objects.get(username="patrizia.huggel@eiger-versicherung.ch"), + user=User.objects.get(username="patrizia.huggel@eiger-versicherungen.ch"), role=CourseSessionUser.Role.EXPERT, ) csu.expert.add(Circle.objects.get(slug="überbetriebliche-kurse-lp-circle-einstieg")) diff --git a/server/vbv_lernwelt/media_library/create_default_media_library.py b/server/vbv_lernwelt/media_library/create_default_media_library.py index 246bd6d3..3650e068 100644 --- a/server/vbv_lernwelt/media_library/create_default_media_library.py +++ b/server/vbv_lernwelt/media_library/create_default_media_library.py @@ -131,25 +131,25 @@ die der Fahrzeugbesitzer und die Fahrzeugbesitzerin in einem grösseren Schadenf create_internal_link_block( InternalLinkBlockFactory( title="Circle: Einstieg – Lernsequenz: Anwenden", - url="/learn/versicherungsvermittlerin-lp/einstieg#lu-fahrzeug", + url="/learn/versicherungsvermittler-in-lp/einstieg#lu-fahrzeug", ) ), create_internal_link_block( InternalLinkBlockFactory( title="Circle: Analyse – Lernsequenz: Anwenden", - url="/learn/versicherungsvermittlerin-lp/analyse#lu-fahrzeug", + url="/learn/versicherungsvermittler-in-lp/analyse#lu-fahrzeug", ) ), create_internal_link_block( InternalLinkBlockFactory( title="Circle: Lösung – Lernsequenz: Anwenden", - url="/learn/versicherungsvermittlerin-lp/lösung#lu-fahrzeug", + url="/learn/versicherungsvermittler-in-lp/lösung#lu-fahrzeug", ) ), create_internal_link_block( InternalLinkBlockFactory( title="Circle: Abschluss – Lernsequenz: Anwenden", - url="/learn/versicherungsvermittlerin-lp/abschluss#lu-fahrzeug", + url="/learn/versicherungsvermittler-in-lp/abschluss#lu-fahrzeug", ) ), ], @@ -161,14 +161,14 @@ die der Fahrzeugbesitzer und die Fahrzeugbesitzerin in einem grösseren Schadenf RelativeLinkBlockFactory( title="Rechtsstreitigkeiten", description="VBV 303/12.3 Verkehrsrechtsschutz", - url="/media/versicherungsvermittlerin-media/category/rechtsstreitigkeiten", + url="/media/versicherungsvermittler-in-media/category/rechtsstreitigkeiten", ) ), create_relative_link_block( RelativeLinkBlockFactory( title="Reisen", description="VBV 303/13 Reiseversicherung", - url="/media/versicherungsvermittlerin-media/category/reisen", + url="/media/versicherungsvermittler-in-media/category/reisen", ) ), ], @@ -236,25 +236,25 @@ Diese können negative Folgen verschiedener Art nach sich ziehen, darunter recht create_internal_link_block( InternalLinkBlockFactory( title="Circle: Einstieg – Lernsequenz: Anwenden", - url="/learn/versicherungsvermittlerin-lp/einstieg#lu-reisen", + url="/learn/versicherungsvermittler-in-lp/einstieg#lu-reisen", ) ), create_internal_link_block( InternalLinkBlockFactory( title="Circle: Analyse – Lernsequenz: Anwenden", - url="/learn/versicherungsvermittlerin-lp/analyse#lu-reisen", + url="/learn/versicherungsvermittler-in-lp/analyse#lu-reisen", ) ), create_internal_link_block( InternalLinkBlockFactory( title="Circle: Lösung – Lernsequenz: Anwenden", - url="/learn/versicherungsvermittlerin-lp/lösung#lu-reisen", + url="/learn/versicherungsvermittler-in-lp/lösung#lu-reisen", ) ), create_internal_link_block( InternalLinkBlockFactory( title="Circle: Abschluss – Lernsequenz: Anwenden", - url="/learn/versicherungsvermittlerin-lp/abschluss#lu-reisen", + url="/learn/versicherungsvermittler-in-lp/abschluss#lu-reisen", ) ), ], @@ -266,21 +266,21 @@ Diese können negative Folgen verschiedener Art nach sich ziehen, darunter recht RelativeLinkBlockFactory( title="Haushalt", description="VBV 303/03 Hausratversicherung", - url="/media/versicherungsvermittlerin-media/category/haushalt", + url="/media/versicherungsvermittler-in-media/category/haushalt", ) ), create_relative_link_block( RelativeLinkBlockFactory( title="Rechtsstreitigkeiten", desciption="VBV 303/12 Rechtschutzversicherung", - url="/media/versicherungsvermittlerin-media/category/rechtsstreitigkeiten", + url="/media/versicherungsvermittler-in-media/category/rechtsstreitigkeiten", ) ), create_relative_link_block( RelativeLinkBlockFactory( title="Gesundheit", description="VBV 304/Teil E Obligatorische Krankenversicherung", - url="/media/versicherungsvermittlerin-media/category/gesundheit", + url="/media/versicherungsvermittler-in-media/category/gesundheit", ) ), ], diff --git a/server/vbv_lernwelt/media_library/tests/media_library_factories.py b/server/vbv_lernwelt/media_library/tests/media_library_factories.py index 89d329d4..37142810 100644 --- a/server/vbv_lernwelt/media_library/tests/media_library_factories.py +++ b/server/vbv_lernwelt/media_library/tests/media_library_factories.py @@ -81,7 +81,7 @@ class InternalLinkBlockFactory(wagtail_factories.StructBlockFactory): title = "Platzhalter interner Link" description = "Link to a Learning Content" link_display_text = "Lerneinheit anzeigen" - url = "/learn/versicherungsvermittlerin-lp/basis" + url = "/learn/versicherungsvermittler-in-lp/basis" # TODO: page = blocks.PageChooserBlock mit Titel etc From fb42625354bca0f1e427a6075306637aec4cd9d8 Mon Sep 17 00:00:00 2001 From: Christian Cueni Date: Wed, 14 Dec 2022 07:58:16 +0100 Subject: [PATCH 06/13] Allow multi-circle selection in cockpit --- client/src/pages/cockpit/CockpitIndexPage.vue | 11 ++--------- client/src/stores/cockpit.ts | 17 ++++++++++++++--- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/client/src/pages/cockpit/CockpitIndexPage.vue b/client/src/pages/cockpit/CockpitIndexPage.vue index 38714db5..ff5a899e 100644 --- a/client/src/pages/cockpit/CockpitIndexPage.vue +++ b/client/src/pages/cockpit/CockpitIndexPage.vue @@ -27,7 +27,6 @@ function userCountStatus(userId: number) { } const data = { - circles: ["KMU Teil 1", "KMU Teil 2", "3-Säuli-Prinzip"], transferProgress: { fail: 0, success: 3, @@ -35,17 +34,11 @@ const data = { }, }; -const selectedCircle = ref(1); - function setActiveClasses(id: number) { - return cockpitStore.selectedCircle === id + return cockpitStore.selectedCircles.indexOf(id) > -1 ? ["bg-blue-900", "text-white"] : ["text-bg-900"]; } - -function setActiveCircle(id: number) { - cockpitStore.selectedCircle = id; -}