Merge branch 'feature/demo-oktober-data' into develop

This commit is contained in:
Daniel Egger 2022-10-07 09:54:23 +02:00
commit b19384ec21
48 changed files with 1978 additions and 479 deletions

View File

@ -5,10 +5,17 @@ log.debug("AppFooter created");
</script>
<template>
<footer class="px-8 py-4 bg-gray-200 border-t border-gray-500 flex">
<footer
class="px-8 py-4 bg-gray-200 border-t border-gray-500 flex flex-col lg:flex-row"
>
<div>@2022 VBV</div>
<div class="lg:ml-8">FAQ</div>
<div class="lg:ml-8">Datenschutzbestimmungen</div>
<div class="lg:ml-8">Impressum</div>
<div class="flex-grow"></div>
<div>VBV_VERSION_BUILD_NUMBER_VBV</div>
<div class="lg:ml-8">Deutsch</div>
<div class="lg:ml-8">Kontakt</div>
</footer>
</template>

View File

@ -145,7 +145,7 @@ const profileDropdownData = [
>
<router-link
v-if="inLearningPath()"
to="/learn/versicherungsvermittlerin"
to="/learn/versicherungsvermittlerin-lp"
class="nav-item"
:class="{ 'nav-item--active': inLearningPath() }"
>

View File

@ -236,20 +236,8 @@ function render() {
<pre hidden>{{ pieData }}</pre>
<pre hidden>{{ render() }}</pre>
<svg class="circle-visualization h-full">
<circle
v-if="!circleStore.circle"
:cx="width / 2"
:cy="height / 2"
:r="radius"
:color="colors.gray[300]"
/>
<circle
v-if="!circleStore.circle"
:cx="width / 2"
:cy="height / 2"
:r="radius / 2.5"
color="white"
/>
<circle :cx="width / 2" :cy="height / 2" :r="radius" :color="colors.gray[300]" />
<circle :cx="width / 2" :cy="height / 2" :r="radius / 2.5" color="white" />
</svg>
</div>
</template>

View File

@ -30,14 +30,14 @@ const block = computed(() => {
type="button"
class="btn-text inline-flex items-center px-3 py-2 font-normal"
data-cy="close-learning-content"
@click="circleStore.closeLearningContent()"
@click="circleStore.closeLearningContent(props.learningContent)"
>
<it-icon-arrow-left class="-ml-1 mr-1 h-5 w-5"></it-icon-arrow-left>
<span class="hidden lg:inline">zurück zum Circle</span>
</button>
<h1 class="text-xl hidden lg:block" data-cy="ln-title">
{{ learningContent?.title }}
{{ learningContent.title }}
</h1>
<button
@ -50,13 +50,11 @@ const block = computed(() => {
</button>
</nav>
<div v-if="block.type === 'exercise'" class="h-screen">
<div v-if="block.type === 'exercise' || block.type === 'test'" class="h-screen">
<iframe width="100%" height="100%" scrolling="no" :src="block.value.url" />
</div>
<div v-else class="container-medium">
<p>{{ block.value.description }}</p>
<div v-if="block.type === 'video'">
<iframe
class="mt-8 w-full aspect-video"
@ -68,6 +66,22 @@ const block = computed(() => {
>
</iframe>
</div>
<div v-else-if="block.type === 'media_library'" class="mt-4 lg:mt-12">
<h1>{{ learningContent.title }}</h1>
<p class="text-xl my-4 lg:my-8">{{ block.value.description }}</p>
<a :href="block.value.url" target="_blank" class="button btn-primary">
Mediathek öffnen
</a>
</div>
<div v-else-if="block.type === 'placeholder'" class="mt-4 lg:mt-12">
<p class="text-xl my-4">{{ block.value.description }}</p>
<h1>{{ learningContent.title }}</h1>
</div>
<div v-else class="text-xl my-4">{{ block.value.description }}</div>
</div>
</div>
</template>

View File

@ -37,10 +37,11 @@ const props = defineProps<{
v-else-if="props.learningContentType === 'resource'"
class="w-6 h-6"
/>
<it-icon-lc-document
<it-icon-lc-resource
v-else-if="props.learningContentType === 'document'"
class="w-6 h-6"
/>
<it-icon-lc-document v-else class="w-6 h-6" />
<p class="whitespace-nowrap">
{{ learningContentTypesToName.get(props.learningContentType) }}
</p>

View File

@ -99,6 +99,7 @@ const learningSequenceBorderClass = computed(() => {
>
<div
v-for="learningUnit in learningSequence.learningUnits"
:id="learningUnit.slug"
:key="learningUnit.id"
class="pt-3 lg:pt-6"
>
@ -155,26 +156,30 @@ const learningSequenceBorderClass = computed(() => {
</div>
<div
v-if="learningUnit.id"
v-if="learningUnit.children.length"
class="hover:cursor-pointer"
:data-cy="`${learningUnit.slug}`"
@click="circleStore.openSelfEvaluation(learningUnit)"
>
<div
v-if="circleStore.calcSelfEvaluationStatus(learningUnit)"
class="flex items-center gap-4 pb-3 lg:pb-6"
class="flex items-center gap-4 pb-3 lg:pb-6 self-evaluation-success"
>
<it-icon-smiley-happy class="w-8 h-8 flex-none" />
<it-icon-smiley-happy class="w-8 h-8 flex-none" data-cy="success" />
<div>Selbsteinschätzung: Ich kann das.</div>
</div>
<div
v-else-if="circleStore.calcSelfEvaluationStatus(learningUnit) === false"
class="flex items-center gap-4 pb-3 lg:pb-6"
class="flex items-center gap-4 pb-3 lg:pb-6 self-evaluation-fail"
>
<it-icon-smiley-thinking class="w-8 h-8 flex-none" />
<it-icon-smiley-thinking class="w-8 h-8 flex-none" data-cy="fail" />
<div>Selbsteinschätzung: Muss ich nochmals anschauen</div>
</div>
<div v-else class="flex items-center gap-4 pb-3 lg:pb-6">
<it-icon-smiley-neutral class="w-8 h-8 flex-none" />
<div
v-else
class="flex items-center gap-4 pb-3 lg:pb-6 self-evaluation-unknown"
>
<it-icon-smiley-neutral class="w-8 h-8 flex-none" data-cy="unknown" />
<div>Selbsteinschätzung</div>
</div>
</div>

View File

@ -26,7 +26,7 @@ function handleContinue() {
state.questionIndex += 1;
} else {
log.debug("continue to next learning content");
circleStore.continueFromSelfEvaluation();
circleStore.continueFromSelfEvaluation(props.learningUnit);
}
}
</script>
@ -39,18 +39,27 @@ function handleContinue() {
<button
type="button"
class="btn-text inline-flex items-center px-3 py-2 font-normal"
@click="circleStore.closeSelfEvaluation()"
@click="circleStore.closeSelfEvaluation(props.learningUnit)"
>
<it-icon-arrow-left class="-ml-1 mr-1 h-5 w-5"></it-icon-arrow-left>
<span class="hidden lg:inline">zurück zum Circle</span>
</button>
<h1 class="text-xl hidden lg:block">{{ learningUnit.title }}</h1>
<h1 class="text-xl hidden lg:block" data-cy="ln-title">
Selbsteinschätzung {{ learningUnit.title }}
</h1>
<button type="button" class="btn-blue" @click="handleContinue()">Weiter</button>
<button
type="button"
class="btn-blue"
data-cy="complete-and-continue"
@click="handleContinue()"
>
Weiter
</button>
</nav>
<div class="mx-auto max-w-6xl px-4 lg:px-8 py-4">
<div class="container-medium">
<div class="mt-2 lg:mt-8 text-gray-700">
Schritt {{ state.questionIndex + 1 }} von {{ questions.length }}
</div>
@ -73,6 +82,7 @@ function handleContinue() {
'border-2': currentQuestion.completion_status === 'success',
'border-gray-500': currentQuestion.completion_status !== 'success',
}"
data-cy="success"
@click="circleStore.markCompletion(currentQuestion, 'success')"
>
<it-icon-smiley-happy class="w-16 h-16 mr-4"></it-icon-smiley-happy>
@ -85,6 +95,7 @@ function handleContinue() {
'border-2': currentQuestion.completion_status === 'fail',
'border-gray-500': currentQuestion.completion_status !== 'fail',
}"
data-cy="fail"
@click="circleStore.markCompletion(currentQuestion, 'fail')"
>
<it-icon-smiley-thinking class="w-16 h-16 mr-4"></it-icon-smiley-thinking>

View File

@ -1,7 +1,7 @@
<script setup lang="ts">
import MediaLink from "@/components/mediaLibrary/MediaLink.vue";
export interface Props {
interface Props {
title: string;
description: string;
linkText: string;
@ -18,7 +18,7 @@ const props = withDefaults(defineProps<Props>(), {
</script>
<template>
<div class="border-gray-500 border flex p-4 items-center">
<div class="border-gray-500 border flex flex-col lg:flex-row p-4 items-center">
<img class="mr-6" :src="icon" />
<div>
<h4 class="mb-2 text-bold">{{ title }}</h4>

View File

@ -16,8 +16,8 @@ const props = withDefaults(defineProps<Props>(), {
<div class="bg-white p-8 flex justify-between">
<div>
<h3 class="mb-4">{{ title }}</h3>
<p class="mb-4">{{ description }}</p>
<router-link :to="link" class="inline-flex items-center font-normal">
<p class="mb-4 text-xl">{{ description }}</p>
<router-link :to="link" class="text-xl inline-flex items-center font-normal">
<span class="inline">{{ call2Action }}</span>
<it-icon-arrow-right class="ml-1 h-5 w-5"></it-icon-arrow-right>
</router-link>
@ -25,7 +25,7 @@ const props = withDefaults(defineProps<Props>(), {
<div
v-if="icon"
:class="[`bg-${icon}`]"
class="bg-contain bg-no-repeat bg-right w-2/6 -mr-8"
class="hidden lg:block bg-contain bg-no-repeat bg-right w-2/6 -mr-8"
></div>
</div>
</template>

View File

@ -0,0 +1,29 @@
<script setup lang="ts">
import { useUserStore } from "@/stores/user";
import * as log from "loglevel";
log.debug("CockpitView created");
const userStore = useUserStore();
</script>
<template>
<main class="px-8 py-8 lg:px-12 lg:py-12 bg-gray-200">
<div class="container-medium">
<h1 data-cy="welcome-message">Willkommen, {{ userStore.first_name }}</h1>
<h2 class="mt-12">Deine Kurse</h2>
<div class="mt-8 p-8 break-words bg-white max-w-xl">
<h3>Versicherungsvermittler/in</h3>
<div class="mt-4">
<router-link class="btn-blue" to="/learn/versicherungsvermittlerin-lp">
Weiter geht's
</router-link>
</div>
</div>
</div>
</main>
</template>
<style scoped></style>

View File

@ -1,27 +0,0 @@
<script setup lang="ts">
import { useUserStore } from "@/stores/user";
import * as log from "loglevel";
log.debug("CockpitView created");
const userStore = useUserStore();
</script>
<template>
<main class="px-8 py-8 lg:px-12 lg:py-12 bg-gray-200">
<h1 data-cy="welcome-message">Willkommen, {{ userStore.first_name }}</h1>
<h2 class="mt-12">Deine Kurse</h2>
<div class="mt-8 p-8 break-words bg-white max-w-xl">
<h3>Versicherungsvermittler/in</h3>
<div class="mt-4">
<router-link class="btn-blue" to="/learn/versicherungsvermittlerin-lp">
Weiter geht's
</router-link>
</div>
</div>
</main>
</template>
<style scoped></style>

View File

@ -0,0 +1,66 @@
<script setup lang="ts">
import { useUserStore } from "@/stores/user";
import * as log from "loglevel";
import { reactive } from "vue";
import { useRoute } from "vue-router";
const route = useRoute();
log.debug("LoginView.vue created");
log.debug(route.query);
const state = reactive({
username: "",
password: "",
});
const userStore = useUserStore();
</script>
<template>
<main class="px-8 py-8 lg:px-12 lg:py-12 bg-gray-200">
<div class="container-medium">
<h1 class="mb-8">Login</h1>
<form
class="bg-white p-4 lg:p-8"
@submit.prevent="
userStore.handleLogin(state.username, state.password, route.query.next)
"
>
<div class="mb-4">
<label class="block mb-1" for="email">Username</label>
<input
id="username"
v-model="state.username"
type="text"
name="username"
class="py-2 px-3 border border-gray-500 mt-1 block w-96"
/>
</div>
<div class="mb-4">
<label class="block mb-1" for="password">Password</label>
<input
id="password"
v-model="state.password"
type="password"
name="password"
class="py-2 px-3 border border-gray-500 mt-1 block w-96"
/>
</div>
<div>
<input
data-cy="login-button"
type="submit"
value="Login"
class="btn-primary"
/>
</div>
</form>
<p class="pt-8"><a href="/sso/login/">Login mit SSO</a></p>
</div>
</main>
</template>
<style scoped></style>

View File

@ -1,58 +0,0 @@
<script setup lang="ts">
import { useUserStore } from "@/stores/user";
import * as log from "loglevel";
import { reactive } from "vue";
import { useRoute } from "vue-router";
const route = useRoute();
log.debug("LoginView.vue created");
log.debug(route.query);
const state = reactive({
username: "",
password: "",
});
const userStore = useUserStore();
</script>
<template>
<main class="px-8 py-8">
<h1>Login</h1>
<form
@submit.prevent="
userStore.handleLogin(state.username, state.password, route.query.next)
"
>
<div class="mt-8 mb-4">
<label class="block mb-1" for="email">Username</label>
<input
id="username"
v-model="state.username"
type="text"
name="username"
class="py-2 px-3 border border-gray-500 mt-1 block w-96"
/>
</div>
<div class="mb-4">
<label class="block mb-1" for="password">Password</label>
<input
id="password"
v-model="state.password"
type="password"
name="password"
class="py-2 px-3 border border-gray-500 mt-1 block w-96"
/>
</div>
<div>
<input data-cy="login-button" type="submit" value="Login" class="btn-primary" />
</div>
</form>
<p class="pt-8"><a href="/sso/login/">Login mit SSO</a></p>
</main>
</template>
<style scoped></style>

View File

@ -40,13 +40,25 @@ onMounted(async () => {
try {
await circleStore.loadCircle(props.learningPathSlug, props.circleSlug);
if (route.hash.startsWith("#ls-")) {
const hashLearningSequence = circleStore.circle?.learningSequences.find((ls) => {
return ls.slug.endsWith(route.hash.replace("#", ""));
});
if (hashLearningSequence) {
if (route.hash.startsWith("#ls-") || route.hash.startsWith("#lu-")) {
const slugEnd = route.hash.replace("#", "");
let wagtailPage = null;
if (slugEnd.startsWith("ls-")) {
wagtailPage = circleStore.circle?.learningSequences.find((ls) => {
return ls.slug.endsWith(slugEnd);
});
} else if (slugEnd.startsWith("lu-")) {
const learningUnits = circleStore.circle?.learningSequences.flatMap(
(ls) => ls.learningUnits
);
wagtailPage = learningUnits.find((lu) => {
return lu.slug.endsWith(slugEnd);
});
}
if (wagtailPage) {
document
.getElementById(hashLearningSequence.slug)
.getElementById(wagtailPage.slug)
?.scrollIntoView({ behavior: "smooth" });
}
}

View File

@ -6,7 +6,7 @@ import { useUserStore } from "@/stores/user";
import { onMounted } from "vue";
import LearningPathDiagram from "@/components/learningPath/LearningPathDiagram.vue";
import LearningPathViewVertical from "@/pages/LearningPathViewVertical.vue";
import LearningPathViewVertical from "@/components/learningPath/LearningPathViewVertical.vue";
import type { LearningPath } from "@/services/learningPath";
log.debug("LearningPathView created");
@ -74,42 +74,43 @@ const createContinueUrl = (learningPath: LearningPath): [string, boolean] => {
></LearningPathDiagram>
</div>
<h1 data-cy="learning-path-title" class="m-6 lg:m-12">
{{ learningPathStore.learningPath.title }}
</h1>
<div
class="bg-white m-6 lg:m-12 p-8 flex flex-col lg:flex-row divide-y lg:divide-y-0 lg:divide-x divide-gray-500 justify-start"
>
<div class="p-4 lg:p-8 flex-auto">
<h2>Willkommmen zurück, {{ userStore.first_name }}</h2>
<p class="mt-4 text-xl"></p>
</div>
<div class="container-large">
<h1 data-cy="learning-path-title" class="mt-6 lg:mt-12 mb-6">
{{ learningPathStore.learningPath.title }}
</h1>
<div
v-if="learningPathStore.learningPath.nextLearningContent"
class="p-4 lg:p-8 flex-2"
class="bg-white p-4 flex flex-col lg:flex-row divide-y lg:divide-y-0 lg:divide-x divide-gray-500 justify-start"
>
Nächster Schritt
<h3>
{{
learningPathStore.learningPath.nextLearningContent.parentCircle.title
}}:
{{
learningPathStore.learningPath.nextLearningContent
.parentLearningSequence?.title
}}
</h3>
<router-link
class="mt-4 btn-blue"
:to="createContinueUrl(learningPathStore.learningPath)[0]"
data-cy="lp-continue-button"
translate
<div class="p-4 lg:p-8 flex-auto">
<h2>Willkommmen zurück, {{ userStore.first_name }}</h2>
<p class="mt-4 text-xl"></p>
</div>
<div
v-if="learningPathStore.learningPath.nextLearningContent"
class="p-4 lg:p-8 flex-2"
>
<span v-if="createContinueUrl(learningPathStore.learningPath)[1]">
Los geht's
</span>
<span v-else>Weiter geht's</span>
</router-link>
Nächster Schritt
<h3>
{{
learningPathStore.learningPath.nextLearningContent.parentCircle.title
}}:
{{
learningPathStore.learningPath.nextLearningContent
.parentLearningSequence?.title
}}
</h3>
<router-link
class="mt-4 btn-blue"
:to="createContinueUrl(learningPathStore.learningPath)[0]"
data-cy="lp-continue-button"
translate
>
<span v-if="createContinueUrl(learningPathStore.learningPath)[1]">
Los geht's
</span>
<span v-else>Weiter geht's</span>
</router-link>
</div>
</div>
</div>
<div class="topic"></div>

View File

@ -52,27 +52,32 @@ const hasMoreItemsForType = (itemType: string, items: object[]) => {
<MLCategoryLayout>
<template #header>
<div class="flex justify-between">
<div class="w-5/12">
<div class="lg:w-6/12">
<h3 class="font-normal text-large mb-3">Handlungsfeld</h3>
<h1 class="mb-4 lg:mb-8">{{ mediaCategory.title }}</h1>
<p>{{ mediaCategory.introduction_text }}</p>
<p class="text-xl">{{ mediaCategory.introduction_text }}</p>
</div>
<div>
<img
class="hidden lg:block float-right"
:src="'/static/icons/demo/category-large.png'"
/>
</div>
<img class="w-5/12" :src="mediaCategory.icon" />
</div>
</template>
<template #body>
<section class="mb-20">
<section class="mb-20 mt-8 lg:w-2/3">
<h2 class="mb-4">{{ mediaCategory.description_title }}</h2>
<p class="mb-4 lg:w-2/3">{{ mediaCategory.description_text }}</p>
<p class="mb-4">{{ mediaCategory.description_text }}</p>
<ul>
<li
v-for="item in mediaCategory.items"
:key="item"
class="mb-2 h-10 leading-10 flex items-center"
class="mb-2 flex items-center"
>
<span
class="text-sky-500 bg-[url('/static/icons/icon-check.svg')] bg-no-repeat h-10 w-10 mr-2"
></span>
<it-icon-check
class="h-8 w-8 text-sky-500 mr-4 flex-none"
></it-icon-check>
{{ item.value }}
</li>
</ul>
@ -84,6 +89,9 @@ const hasMoreItemsForType = (itemType: string, items: object[]) => {
>
<section v-if="content_collection.value?.contents?.length" class="mb-20">
<h2 class="mb-4">{{ content_collection.value.title }}</h2>
<p class="mb-4 lg:w-2/3">
{{ content_collection.value.description }}
</p>
<ul
:class="{
'grid gap-4 grid-cols-1 lg:grid-cols-2': displayAsCard(

View File

@ -25,8 +25,8 @@ watch(dropdownSelected, (newValue) =>
</script>
<template>
<div class="mx-auto max-w-5xl">
<div class="flex flex-col lg:flex-row items-center justify-between mb-10">
<div class="container-large">
<div class="flex flex-col lg:flex-row items-center justify-between mb-10 mt-6">
<h1>Handlungsfelder</h1>
<!-- <ItDropdownSelect v-model="dropdownSelected" :items="mediaStore.availableLearningPaths"></ItDropdownSelect>-->
</div>

View File

@ -6,16 +6,24 @@ const router = useRouter();
<template>
<Teleport to="body">
<div class="px-16 fixed top-0 overflow-y-scroll bg-white h-full w-full">
<div class="-mx-16 pt-4 pb-24 px-16 mb-20 bg-gray-200">
<nav>
<a class="block my-9 cursor-pointer flex items-center" @click="router.go(-1)"
><it-icon-arrow-left /><span>zurück</span></a
>
</nav>
<slot name="header"></slot>
<div class="fixed top-0 overflow-y-scroll bg-white h-full w-full">
<div class="bg-gray-200">
<div class="container-large">
<nav>
<a
class="block my-9 cursor-pointer flex items-center"
@click="router.go(-1)"
>
<it-icon-arrow-left />
<span>zurück</span></a
>
</nav>
<slot name="header"></slot>
</div>
</div>
<div class="container-large">
<slot name="body"></slot>
</div>
<slot name="body"></slot>
</div>
</Teleport>
</template>
@ -24,6 +32,7 @@ const router = useRouter();
.it-icon-hf {
color: blue;
}
.it-icon-hf > * {
@apply m-auto;
}

View File

@ -26,8 +26,8 @@ watch(dropdownSelected, (newValue) =>
</script>
<template>
<div class="mx-auto max-w-5xl">
<div class="flex flex-col lg:flex-row items-center justify-between mb-10">
<div class="container-large">
<div class="flex flex-col lg:flex-row items-center justify-between mb-12 mt-6">
<h1>Mediathek</h1>
<!-- <ItDropdownSelect-->
<!-- v-model="dropdownSelected"-->

View File

@ -24,18 +24,18 @@ onMounted(async () => {
<template>
<div class="bg-gray-200">
<nav class="h-12 px-6 py-2 border-b border-gray-500 bg-white">
<ul class="flex">
<nav class="px-6 py-4 border-b border-gray-500 bg-white">
<ul class="flex text-xl flex-col lg:flex-row">
<li>Übersicht</li>
<li class="ml-10">Handlungsfelder</li>
<li class="ml-10">Allgemeines zu Versicherungen</li>
<li class="ml-10">Lernmedien</li>
<li class="ml-10">
<li class="lg:ml-12">Handlungsfelder</li>
<li class="lg:ml-12">Allgemeines zu Versicherungen</li>
<li class="lg:ml-12">Lernmedien</li>
<li class="lg:ml-12">
<a href="https://www.vbv.ch/de/der-vbv/lernen-lehren/lexikon">Lexikon</a>
</li>
</ul>
</nav>
<main class="px-8 py-8">
<main>
<router-view></router-view>
</main>
</div>

View File

@ -1,11 +1,18 @@
import CockpitView from "@/pages/CockpitView.vue";
import LoginView from "@/pages/LoginView.vue";
import CockpitView from "@/pages/CockpitPage.vue";
import LoginView from "@/pages/LoginPage.vue";
import { redirectToLoginIfRequired, updateLoggedIn } from "@/router/guards";
import { useAppStore } from "@/stores/app";
import { createRouter, createWebHistory } from "vue-router";
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
scrollBehavior(to, from, savedPosition) {
if (savedPosition) {
return savedPosition;
} else {
return { top: 0 };
}
},
routes: [
{
path: "/login",
@ -20,10 +27,6 @@ const router = createRouter({
name: "home",
component: CockpitView,
},
{
path: "/shop",
component: () => import("@/pages/ShopView.vue"),
},
{
path: "/media/:mediaLibraryPageSlug",
props: true,
@ -49,37 +52,41 @@ const router = createRouter({
},
],
},
{
path: "/messages",
component: () => import("@/pages/MessagesView.vue"),
},
{
path: "/profile",
component: () => import("@/pages/ProfileView.vue"),
},
{
path: "/learn/:learningPathSlug",
component: () => import("../pages/LearningPathView.vue"),
component: () => import("../pages/learningPath/LearningPathPage.vue"),
props: true,
},
{
path: "/learn/:learningPathSlug/:circleSlug",
component: () => import("../pages/CircleView.vue"),
component: () => import("../pages/learningPath/CirclePage.vue"),
props: true,
},
{
path: "/learn/:learningPathSlug/:circleSlug/evaluate/:learningUnitSlug",
component: () => import("../pages/LearningUnitSelfEvaluationView.vue"),
component: () => import("../pages/learningPath/SelfEvaluationPage.vue"),
props: true,
},
{
path: "/learn/:learningPathSlug/:circleSlug/:contentSlug",
component: () => import("../pages/LearningContentView.vue"),
component: () => import("../pages/learningPath/LearningContentPage.vue"),
props: true,
},
{
path: "/shop",
component: () => import("@/pages/ShopPage.vue"),
},
{
path: "/messages",
component: () => import("@/pages/MessagesPage.vue"),
},
{
path: "/profile",
component: () => import("@/pages/ProfilePage.vue"),
},
{
path: "/styleguide",
component: () => import("../pages/StyleGuideView.vue"),
component: () => import("../pages/StyleGuidePage.vue"),
meta: {
public: true,
},

View File

@ -9,7 +9,7 @@ import type {
LearningContent,
LearningSequence,
LearningUnit,
LearningUnitQuestion,
LearningUnitPerformanceCriteria,
} from "@/types";
function _createEmptyLearningUnit(
@ -66,6 +66,7 @@ export function parseLearningSequences(
learningUnit = Object.assign(child, {
learningContents: [],
parentLearningSequence: learningSequence,
parentCircle: circle,
children: child.children.map((c) => {
c.parentLearningUnit = learningUnit;
c.parentLearningSequence = learningSequence;
@ -158,12 +159,12 @@ export class Circle implements CourseWagtailPage {
);
}
public get flatChildren(): (LearningContent | LearningUnitQuestion)[] {
const result: (LearningContent | LearningUnitQuestion)[] = [];
public get flatChildren(): (LearningContent | LearningUnitPerformanceCriteria)[] {
const result: (LearningContent | LearningUnitPerformanceCriteria)[] = [];
this.learningSequences.forEach((learningSequence) => {
learningSequence.learningUnits.forEach((learningUnit) => {
learningUnit.children.forEach((learningUnitQuestion) => {
result.push(learningUnitQuestion);
learningUnit.children.forEach((performanceCriteria) => {
result.push(performanceCriteria);
});
learningUnit.learningContents.forEach((learningContent) => {
result.push(learningContent);

View File

@ -33,7 +33,7 @@ export class LearningPath implements CourseWagtailPage {
return new LearningPath(
json.id,
json.slug,
json.title,
json.course.title,
json.translation_key,
json.frontend_url,
json.course.id,

View File

@ -9,7 +9,7 @@ import type {
CourseCompletionStatus,
LearningContent,
LearningUnit,
LearningUnitQuestion,
LearningUnitPerformanceCriteria,
} from "@/types";
export type CircleStoreState = {
@ -17,6 +17,16 @@ export type CircleStoreState = {
page: "INDEX" | "OVERVIEW";
};
function createLearningUnitHash(learningUnit: LearningUnit | undefined) {
const luSlug = learningUnit?.slug;
const circleSlug = learningUnit?.parentCircle?.slug;
if (luSlug && circleSlug) {
return "#" + luSlug.replace(`${circleSlug}-`, "");
}
return "";
}
export const useCircleStore = defineStore({
id: "circle",
state: () => {
@ -76,7 +86,7 @@ export const useCircleStore = defineStore({
return learningUnit;
},
async markCompletion(
page: LearningContent | LearningUnitQuestion,
page: LearningContent | LearningUnitPerformanceCriteria,
completion_status: CourseCompletionStatus = "success"
) {
try {
@ -98,9 +108,10 @@ export const useCircleStore = defineStore({
path: learningContent.frontend_url,
});
},
closeLearningContent() {
closeLearningContent(learningContent: LearningContent) {
this.router.push({
path: `${this.circle?.frontend_url}`,
hash: createLearningUnitHash(learningContent.parentLearningUnit),
});
},
openSelfEvaluation(learningUnit: LearningUnit) {
@ -108,9 +119,10 @@ export const useCircleStore = defineStore({
path: learningUnit.frontend_url,
});
},
closeSelfEvaluation() {
closeSelfEvaluation(learningUnit: LearningUnit) {
this.router.push({
path: `${this.circle?.frontend_url}`,
hash: createLearningUnitHash(learningUnit),
});
},
calcSelfEvaluationStatus(learningUnit: LearningUnit) {
@ -139,42 +151,26 @@ export const useCircleStore = defineStore({
currentParent.children.length > 0
) {
// go to self evaluation
// this.openSelfEvaluation(currentParent);
this.closeLearningContent();
this.openSelfEvaluation(currentParent);
} else if (currentLearningContent.nextLearningContent) {
if (
currentLearningContent.parentLearningSequence &&
currentLearningContent.parentLearningSequence.id ===
nextLearningContent?.parentLearningSequence?.id
currentLearningContent.parentLearningUnit &&
currentLearningContent.parentLearningUnit.id ===
nextLearningContent?.parentLearningUnit?.id
) {
this.openLearningContent(currentLearningContent.nextLearningContent);
} else {
this.closeLearningContent();
this.closeLearningContent(currentLearningContent);
}
} else {
this.closeLearningContent();
this.closeLearningContent(currentLearningContent);
}
} else {
log.error("currentLearningContent is undefined");
}
},
continueFromSelfEvaluation() {
this.closeSelfEvaluation();
// if (this.currentSelfEvaluation) {
// const nextContent = this.currentSelfEvaluation.learningContents[this.currentSelfEvaluation.learningContents.length - 1].nextLearningContent;
//
// if (nextContent) {
// if (this.currentSelfEvaluation?.parentLearningSequence?.id === nextContent?.parentLearningSequence?.id) {
// this.openLearningContent(nextContent);
// } else {
// this.closeSelfEvaluation();
// }
// } else {
// this.closeSelfEvaluation();
// }
// } else {
// log.error('currentSelfEvaluation is undefined');
// }
continueFromSelfEvaluation(learningUnit: LearningUnit) {
this.closeSelfEvaluation(learningUnit);
},
},
});

View File

@ -11,7 +11,8 @@ export type LearningContentType =
| "online_training"
| "resource"
| "test"
| "video";
| "video"
| "placeholder";
export interface LearningContentBlock {
type: LearningContentType;
@ -144,8 +145,8 @@ export interface LearningContent extends CourseWagtailPage {
previousLearningContent?: LearningContent;
}
export interface LearningUnitQuestion extends CourseWagtailPage {
type: "learnpath.LearningUnitQuestion";
export interface LearningUnitPerformanceCriteria extends CourseWagtailPage {
type: "competence.PerformanceCriteria";
parentLearningSequence?: LearningSequence;
parentLearningUnit?: LearningUnit;
}
@ -155,7 +156,8 @@ export interface LearningUnit extends CourseWagtailPage {
learningContents: LearningContent[];
minutes: number;
parentLearningSequence?: LearningSequence;
children: LearningUnitQuestion[];
parentCircle?: Circle;
children: LearningUnitPerformanceCriteria[];
last?: boolean;
}
@ -170,7 +172,7 @@ export type CircleChild =
| LearningContent
| LearningUnit
| LearningSequence
| LearningUnitQuestion;
| LearningUnitPerformanceCriteria;
export interface WagtailCircle extends CourseWagtailPage {
type: "learnpath.Circle";

View File

@ -10,4 +10,5 @@ export const learningContentTypesToName = new Map<LearningContentType, string>([
["video", "Video"],
["test", "Test"],
["resource", "Hilfsmittel"],
["placeholder", "Platzhalter"],
]);

View File

@ -60,11 +60,11 @@ svg {
}
.container-medium {
@apply mx-auto max-w-5xl px-4 lg:px-8 py-4;
@apply mx-auto max-w-5xl w-full px-4 lg:px-8 py-4;
}
.container-large {
@apply mx-auto max-w-9xl px-4 lg:px-8 py-4;
@apply mx-auto max-w-6xl w-full px-4 lg:px-8 py-4;
}
}

View File

@ -31,6 +31,10 @@ describe("circle page", () => {
});
it("can open learning contents and complete them by continuing", () => {
cy.get(
'[data-cy="test-lehrgang-lp-circle-analyse-lu-fahrzeug"] > div'
).should("have.class", "self-evaluation-unknown");
cy.get(
'[data-cy="test-lehrgang-lp-circle-analyse-lc-rafael-fasel-wechselt-sein-auto"]'
).click();
@ -43,12 +47,30 @@ describe("circle page", () => {
cy.get('[data-cy="ln-title"]').should("contain", "Fachcheck Fahrzeug");
cy.get('[data-cy="complete-and-continue"]').click();
cy.get('[data-cy="ln-title"]').should(
"contain",
"Selbsteinschätzung Fahrzeug"
);
cy.get('[data-cy="success"]').click();
cy.get('[data-cy="complete-and-continue"]').click();
cy.get('[data-cy="ln-title"]').should(
"contain",
"Selbsteinschätzung Fahrzeug"
);
cy.get('[data-cy="success"]').click();
cy.get('[data-cy="complete-and-continue"]').click();
cy.get(
'[data-cy="test-lehrgang-lp-circle-analyse-lc-rafael-fasel-wechselt-sein-auto"] > .cy-checkbox-checked'
).should("have.class", "cy-checkbox-checked");
cy.get(
'[data-cy="test-lehrgang-lp-circle-analyse-lc-fachcheck-fahrzeug"] > .cy-checkbox-checked'
).should("have.class", "cy-checkbox-checked");
cy.get(
'[data-cy="test-lehrgang-lp-circle-analyse-lu-fahrzeug"] > div'
).should("have.class", "self-evaluation-success");
});
it("continue button works", () => {

View File

@ -130,6 +130,184 @@ def create_default_competence_profile():
items=[("item", i) for i in c["items"]],
)
# Daten anhand von WEVM_Version Oktober 2022
# Einstieg/Beobachten Selbsteinschätzung «Einkommenssicherung»
PerformanceCriteriaFactory(
parent=CompetencePage.objects.get(competence_id="A2"),
competence_id="A2.1",
title="Ich bin fähig je nach (Neu-) Kunde Form und Ort für das Gespräch festzulegen.",
learning_unit=LearningUnit.objects.get(
slug="versicherungsvermittlerin-lp-circle-einstieg-lu-einkommenssicherung"
),
)
PerformanceCriteriaFactory(
parent=CompetencePage.objects.get(competence_id="A2"),
competence_id="A2.2",
title="Ich bin fähig mir intern und extern die nötigen Informationen über den (Neu-) Kunden zu beschaffen.",
learning_unit=LearningUnit.objects.get(
slug="versicherungsvermittlerin-lp-circle-einstieg-lu-einkommenssicherung"
),
)
PerformanceCriteriaFactory(
parent=CompetencePage.objects.get(competence_id="A2"),
competence_id="A2.3",
title="Ich bin fähig die Terminierung auf das Thema Einkommenssicherung auszurichten.",
learning_unit=LearningUnit.objects.get(
slug="versicherungsvermittlerin-lp-circle-einstieg-lu-einkommenssicherung"
),
)
PerformanceCriteriaFactory(
parent=CompetencePage.objects.get(competence_id="A2"),
competence_id="A2.4",
title="Ich bin fähig für das zu führende Gespräch eine Agenda zu erstellen.",
learning_unit=LearningUnit.objects.get(
slug="versicherungsvermittlerin-lp-circle-einstieg-lu-einkommenssicherung"
),
)
PerformanceCriteriaFactory(
parent=CompetencePage.objects.get(competence_id="A2"),
competence_id="A2.5",
title="Ich bin fähig für das Handlungsfeld «Einkommenssicherung» geeignete Hilfsmittel und Unterlagen zusammenzustellen.",
learning_unit=LearningUnit.objects.get(
slug="versicherungsvermittlerin-lp-circle-einstieg-lu-einkommenssicherung"
),
)
PerformanceCriteriaFactory(
parent=CompetencePage.objects.get(competence_id="B1"),
competence_id="B1.1",
title="Ich bin fähig dem Kunden den Gesprächsablauf und den Zeitrahmen (mittels Agenda) aufzuzeigen.",
learning_unit=LearningUnit.objects.get(
slug="versicherungsvermittlerin-lp-circle-einstieg-lu-einkommenssicherung"
),
)
PerformanceCriteriaFactory(
parent=CompetencePage.objects.get(competence_id="B1"),
competence_id="B1.2",
title="Ich bin fähig mich beim Kunden korrekt zu identifizieren (VAG 45).",
learning_unit=LearningUnit.objects.get(
slug="versicherungsvermittlerin-lp-circle-einstieg-lu-einkommenssicherung"
),
)
PerformanceCriteriaFactory(
parent=CompetencePage.objects.get(competence_id="B2"),
competence_id="B2.3",
title="Ich bin fähig alle erforderlichen Unterlagen einzufordern.",
learning_unit=LearningUnit.objects.get(
slug="versicherungsvermittlerin-lp-circle-einstieg-lu-einkommenssicherung"
),
)
# Einstieg / Anwenden Selbsteinschätzung «Fahrzeug»
PerformanceCriteriaFactory(
parent=CompetencePage.objects.get(competence_id="A1"),
competence_id="A1.6",
title="Ich bin fähig im täglichen Kontakt potenzielle Kundinnen und Kunden zu erkennen.",
learning_unit=LearningUnit.objects.get(
slug="versicherungsvermittlerin-lp-circle-einstieg-lu-fahrzeug"
),
)
PerformanceCriteriaFactory(
parent=CompetencePage.objects.get(competence_id="A2"),
competence_id="A2.1",
title="Ich bin fähig je nach (Neu-) Kunde Form und Ort für das Gespräch festzulegen.",
learning_unit=LearningUnit.objects.get(
slug="versicherungsvermittlerin-lp-circle-einstieg-lu-fahrzeug"
),
)
PerformanceCriteriaFactory(
parent=CompetencePage.objects.get(competence_id="A2"),
competence_id="A2.2",
title="Ich bin fähig mir intern und extern die nötigen Informationen über den (Neu-) Kunden zu beschaffen.",
learning_unit=LearningUnit.objects.get(
slug="versicherungsvermittlerin-lp-circle-einstieg-lu-fahrzeug"
),
)
PerformanceCriteriaFactory(
parent=CompetencePage.objects.get(competence_id="A2"),
competence_id="A2.3",
title="Ich bin fähig die Terminierung auf das Thema Fahrzeug auszurichten.",
learning_unit=LearningUnit.objects.get(
slug="versicherungsvermittlerin-lp-circle-einstieg-lu-fahrzeug"
),
)
PerformanceCriteriaFactory(
parent=CompetencePage.objects.get(competence_id="A2"),
competence_id="A2.4",
title="Ich bin fähig für das zu führende Gespräch eine Agenda zu erstellen.",
learning_unit=LearningUnit.objects.get(
slug="versicherungsvermittlerin-lp-circle-einstieg-lu-fahrzeug"
),
)
PerformanceCriteriaFactory(
parent=CompetencePage.objects.get(competence_id="A2"),
competence_id="A2.5",
title="Ich bin fähig für das zu führende Gespräch geeignete Hilfsmittel und Unterlagen zusammenzustellen.",
learning_unit=LearningUnit.objects.get(
slug="versicherungsvermittlerin-lp-circle-einstieg-lu-fahrzeug"
),
)
# Einstieg / Anwenden Selbsteinschätzung «Reisen»
PerformanceCriteriaFactory(
parent=CompetencePage.objects.get(competence_id="A2"),
competence_id="A2.3",
title="Ich bin fähig die Terminierung auf das Thema Reisen auszurichten.",
learning_unit=LearningUnit.objects.get(
slug="versicherungsvermittlerin-lp-circle-einstieg-lu-reisen"
),
)
PerformanceCriteriaFactory(
parent=CompetencePage.objects.get(competence_id="A2"),
competence_id="A2.4",
title="Ich bin fähig für das zu führende Gespräch eine Agenda zu erstellen.",
learning_unit=LearningUnit.objects.get(
slug="versicherungsvermittlerin-lp-circle-einstieg-lu-reisen"
),
)
PerformanceCriteriaFactory(
parent=CompetencePage.objects.get(competence_id="A2"),
competence_id="A2.5",
title="Ich bin fähig für das zu führende Gespräch geeignete Hilfsmittel und Unterlagen zusammenzustellen.",
learning_unit=LearningUnit.objects.get(
slug="versicherungsvermittlerin-lp-circle-einstieg-lu-reisen"
),
)
# Analyse / Beobachten Selbsteinschätzung «Einkommenssicherung»
PerformanceCriteriaFactory(
parent=CompetencePage.objects.get(competence_id="A1"),
competence_id="A1.5",
title="Innerhalb des Handlungsfelds «Einkommenssicherung» bin ich fähig, das Thema Risiko und Sicherheit in einem Gespräch gezielt und auf die Situation des jeweiligen Gesprächspartners bezogen, einfliessen zu lassen.",
learning_unit=LearningUnit.objects.get(
slug="versicherungsvermittlerin-lp-circle-analyse-lu-einkommenssicherung"
),
)
PerformanceCriteriaFactory(
parent=CompetencePage.objects.get(competence_id="B1"),
competence_id="B1.3",
title="Innerhalb des Handlungsfelds «Einkommenssicherung» bin ich fähig, die Ziele und Pläne des Kunden zu ergründen (SOLL).",
learning_unit=LearningUnit.objects.get(
slug="versicherungsvermittlerin-lp-circle-analyse-lu-einkommenssicherung"
),
)
PerformanceCriteriaFactory(
parent=CompetencePage.objects.get(competence_id="B2"),
competence_id="B2.1",
title="Innerhalb des Handlungsfelds «Einkommenssicherung» bin ich fähig, die IST-Situation des Kunden mit der geeigneten Gesprächs-/Fragetechnik zu erfassen.",
learning_unit=LearningUnit.objects.get(
slug="versicherungsvermittlerin-lp-circle-analyse-lu-einkommenssicherung"
),
)
PerformanceCriteriaFactory(
parent=CompetencePage.objects.get(competence_id="B2"),
competence_id="B2.2",
title="Innerhalb des Handlungsfelds «Einkommenssicherung» bin ich fähig, die Risiken aufzuzeigen.",
learning_unit=LearningUnit.objects.get(
slug="versicherungsvermittlerin-lp-circle-analyse-lu-einkommenssicherung"
),
)
# Analyse/Anwenden Selbsteinschätzung «Fahrzeug»
PerformanceCriteriaFactory(
parent=CompetencePage.objects.get(competence_id="B1"),
competence_id="B1.3",
@ -154,3 +332,181 @@ def create_default_competence_profile():
slug="versicherungsvermittlerin-lp-circle-analyse-lu-fahrzeug"
),
)
# Analyse/Anwenden Selbsteinschätzung «Reisen»
PerformanceCriteriaFactory(
parent=CompetencePage.objects.get(competence_id="B1"),
competence_id="B1.3",
title="Innerhalb des Handlungsfelds «Reisen» bin ich fähig, die Ziele und Pläne des Kunden zu ergründen (SOLL).",
learning_unit=LearningUnit.objects.get(
slug="versicherungsvermittlerin-lp-circle-analyse-lu-reisen"
),
)
PerformanceCriteriaFactory(
parent=CompetencePage.objects.get(competence_id="B2"),
competence_id="B2.1",
title="Innerhalb des Handlungsfelds «Reisen» bin ich fähig, die IST-Situation des Kunden mit der geeigneten Gesprächs-/Fragetechnik zu erfassen.",
learning_unit=LearningUnit.objects.get(
slug="versicherungsvermittlerin-lp-circle-analyse-lu-reisen"
),
)
PerformanceCriteriaFactory(
parent=CompetencePage.objects.get(competence_id="B2"),
competence_id="B2.2",
title="Innerhalb des Handlungsfelds «Reisen» bin ich fähig, die Risiken aufzuzeigen.",
learning_unit=LearningUnit.objects.get(
slug="versicherungsvermittlerin-lp-circle-analyse-lu-reisen"
),
)
PerformanceCriteriaFactory(
parent=CompetencePage.objects.get(competence_id="C1"),
competence_id="C1.1",
title="Innerhalb des Handlungsfelds «Reisen» durch eine Bestandesaufnahme der aktuellen Policen zu prüfen, ob die Leistungen dem Bedarf des Kunden entsprechen.",
learning_unit=LearningUnit.objects.get(
slug="versicherungsvermittlerin-lp-circle-analyse-lu-reisen"
),
)
# Lösung/Anwenden Selbsteinschätzung «Fahrzeug»
PerformanceCriteriaFactory(
parent=CompetencePage.objects.get(competence_id="B4"),
competence_id="B4.2",
title="Innerhalb des Handlungsfelds «Fahrzeug» bin ich fähig, dem Kunden die Vorschläge verständlich zu erläutern und die entsprechenden Informationspflichten zu erfüllen",
learning_unit=LearningUnit.objects.get(
slug="versicherungsvermittlerin-lp-circle-analyse-lu-fahrzeug"
),
)
PerformanceCriteriaFactory(
parent=CompetencePage.objects.get(competence_id="B4"),
competence_id="B4.3",
title="Innerhalb des Handlungsfelds «Fahrzeug» bin ich fähig, auf Vorbehalte und/oder Fragen sachlich korrekt und (verhandlungs-)sicher einzugehen.",
learning_unit=LearningUnit.objects.get(
slug="versicherungsvermittlerin-lp-circle-analyse-lu-fahrzeug"
),
)
PerformanceCriteriaFactory(
parent=CompetencePage.objects.get(competence_id="B4"),
competence_id="B4.4",
title="Innerhalb des Handlungsfelds «Fahrzeug» bin ich fähig, nötige Anpassungen flexibel vorzunehmen.",
learning_unit=LearningUnit.objects.get(
slug="versicherungsvermittlerin-lp-circle-analyse-lu-fahrzeug"
),
)
PerformanceCriteriaFactory(
parent=CompetencePage.objects.get(competence_id="C1"),
competence_id="C1.1",
title="Innerhalb des Handlungsfelds «Fahrzeug» bin ich fähig durch eine Bestandesaufnahme der aktuellen Policen zu prüfen, ob die Leistungen dem Bedarf des Kunden entsprechen",
learning_unit=LearningUnit.objects.get(
slug="versicherungsvermittlerin-lp-circle-analyse-lu-fahrzeug"
),
)
PerformanceCriteriaFactory(
parent=CompetencePage.objects.get(competence_id="C1"),
competence_id="C1.2",
title="Innerhalb des Handlungsfelds «Fahrzeug» bin ich fähig, den Kunden bedarfsgerechte Vorschläge für Anpassungen der Versicherungslösung zu unterbreiten (Up-Selling).",
learning_unit=LearningUnit.objects.get(
slug="versicherungsvermittlerin-lp-circle-analyse-lu-fahrzeug"
),
)
# Lösung/Anwenden Selbsteinschätzung «Reisen»
PerformanceCriteriaFactory(
parent=CompetencePage.objects.get(competence_id="B3"),
competence_id="B3.2",
title="Innerhalb des Handlungsfelds «Reisen» bin ich fähig, eine Unterversicherung, eine Doppel- oder Überversicherung, einen fehlenden Versicherungsschutz und mögliches Optimierungspotential festzustellen.",
learning_unit=LearningUnit.objects.get(
slug="versicherungsvermittlerin-lp-circle-analyse-lu-reisen"
),
)
PerformanceCriteriaFactory(
parent=CompetencePage.objects.get(competence_id="B4"),
competence_id="B4.2",
title="Innerhalb des Handlungsfelds «Reisen» bin ich fähig, dem Kunden die Vorschläge verständlich zu erläutern und die entsprechenden Informationspflichten zu erfüllen.",
learning_unit=LearningUnit.objects.get(
slug="versicherungsvermittlerin-lp-circle-analyse-lu-reisen"
),
)
PerformanceCriteriaFactory(
parent=CompetencePage.objects.get(competence_id="B4"),
competence_id="B4.3",
title="Innerhalb des Handlungsfelds «Reisen» bin ich fähig, auf Vorbehalte und/oder Fragen sachlich korrekt und (verhandlungs-)sicher einzugehen.",
learning_unit=LearningUnit.objects.get(
slug="versicherungsvermittlerin-lp-circle-analyse-lu-reisen"
),
)
PerformanceCriteriaFactory(
parent=CompetencePage.objects.get(competence_id="B4"),
competence_id="B4.4",
title="Innerhalb des Handlungsfelds «Reisen» bin ich fähig, nötige Anpassungen flexibel vorzunehmen.",
learning_unit=LearningUnit.objects.get(
slug="versicherungsvermittlerin-lp-circle-analyse-lu-reisen"
),
)
PerformanceCriteriaFactory(
parent=CompetencePage.objects.get(competence_id="C1"),
competence_id="C1.2",
title="Innerhalb des Handlungsfelds «Reisen» bin ich fähig, den Kunden bedarfsgerechte Vorschläge für Anpassungen der Versicherungslösung zu unterbreiten (Up-Selling).",
learning_unit=LearningUnit.objects.get(
slug="versicherungsvermittlerin-lp-circle-analyse-lu-reisen"
),
)
PerformanceCriteriaFactory(
parent=CompetencePage.objects.get(competence_id="C1"),
competence_id="C1.3",
title="Innerhalb des Handlungsfelds «Reisen» bin ich fähig aufgrund des Portfolios passende Zusatzprodukte anzubieten (Cross-Selling).",
learning_unit=LearningUnit.objects.get(
slug="versicherungsvermittlerin-lp-circle-analyse-lu-reisen"
),
)
# Abschluss/Anwenden Selbsteinschätzung «Fahrzeug»
PerformanceCriteriaFactory(
parent=CompetencePage.objects.get(competence_id="A1"),
competence_id="A1.2",
title="Innerhalb des Handlungsfelds «Fahrzeug» bin ich fähig, geeignete Personen wie z.B. Garagisten, Architekten, Treuhänder auf die Vermittlung/Zusammenarbeit anzusprechen.",
learning_unit=LearningUnit.objects.get(
slug="versicherungsvermittlerin-lp-circle-analyse-lu-fahrzeug"
),
)
PerformanceCriteriaFactory(
parent=CompetencePage.objects.get(competence_id="A4"),
competence_id="A4.1",
title="Innerhalb des Handlungsfelds «Fahrzeug» bin ich fähig, Kundendaten in Datenbanken (CRM) korrekt zu erfassen.",
learning_unit=LearningUnit.objects.get(
slug="versicherungsvermittlerin-lp-circle-analyse-lu-fahrzeug"
),
)
PerformanceCriteriaFactory(
parent=CompetencePage.objects.get(competence_id="B4"),
competence_id="B4.6",
title="Innerhalb des Handlungsfelds «Fahrzeug» bin ich fähig, Anträge korrekt auszufüllen.",
learning_unit=LearningUnit.objects.get(
slug="versicherungsvermittlerin-lp-circle-analyse-lu-fahrzeug"
),
)
PerformanceCriteriaFactory(
parent=CompetencePage.objects.get(competence_id="C1"),
competence_id="C1.3",
title="Innerhalb des Handlungsfelds «Fahrzeug» bin ich fähig, aufgrund des Portfolios passende Zusatzprodukte anzubieten (Cross-Selling).",
learning_unit=LearningUnit.objects.get(
slug="versicherungsvermittlerin-lp-circle-analyse-lu-fahrzeug"
),
)
# Abschluss / Anwenden Selbsteinschätzung «Reisen»
PerformanceCriteriaFactory(
parent=CompetencePage.objects.get(competence_id="B4"),
competence_id="B4.6",
title="Innerhalb des Handlungsfelds «Reisen» bin ich fähig, Anträge korrekt auszufüllen.",
learning_unit=LearningUnit.objects.get(
slug="versicherungsvermittlerin-lp-circle-analyse-lu-reisen"
),
)
PerformanceCriteriaFactory(
parent=CompetencePage.objects.get(competence_id="C3"),
competence_id="C3.1",
title="Innerhalb des Handlungsfelds «Reisen» bin ich fähig, Kunden die Vorgehensweise für die Meldung des Schadens nachvollziehbar zu erläutern und sie bei Bedarf zu unterstützen.",
learning_unit=LearningUnit.objects.get(
slug="versicherungsvermittlerin-lp-circle-analyse-lu-reisen"
),
)

View File

@ -28,4 +28,4 @@ def command():
call_command("createcachetable")
call_command("migrate")
call_command("create_default_users")
call_command("create_default_learning_path")
call_command("create_default_courses")

View File

@ -1,6 +1,7 @@
import wagtail_factories
from django.conf import settings
from django.core.management import call_command
from slugify import slugify
from wagtail.models import Locale, Page, Site
from wagtail_localize.models import LocaleSynchronization
@ -26,51 +27,659 @@ from vbv_lernwelt.learnpath.tests.learning_path_factories import (
)
def create_circle(title, learning_path):
return CircleFactory(
title=title,
parent=learning_path,
def create_default_learning_path(user=None, skip_locales=True):
if user is None:
user = User.objects.get(username="info@iterativ.ch")
site = Site.objects.filter(is_default_site=True).first()
if not site:
site = wagtail_factories.SiteFactory(is_default_site=True)
if settings.APP_ENVIRONMENT == "development":
site.port = 8000
site.save()
course_page = CoursePage.objects.get(course_id=COURSE_VERSICHERUNGSVERMITTLERIN_ID)
lp = LearningPathFactory(
title="Lernpfad",
parent=course_page,
)
TopicFactory(title="Basis", is_visible=False, parent=lp)
create_circle_basis(lp)
TopicFactory(title="Gewinnen von Kunden", parent=lp)
create_circle_gewinnen(lp)
TopicFactory(title="Beraten der Kunden", parent=lp)
create_circle_einstieg(lp)
create_circle_analyse(lp)
create_circle_loesung(lp)
create_circle_abschluss(lp)
TopicFactory(title="Betreuen und Ausbauen des Kundenstamms", parent=lp)
create_circle_betreuen(lp)
# circle_analyse = create_circle("Betreuen", lp)
# create_circle_children(circle_analyse, "Betreuen")
#
# TopicFactory(title="Prüfung", is_visible=True, parent=lp)
# circle_analyse = create_circle("Prüfungsvorbereitung", lp)
# create_circle_children(circle_analyse, "Prüfungsvorbereitung")
# locales
if not skip_locales:
locale_de = Locale.objects.get(language_code="de-CH")
locale_fr, _ = Locale.objects.get_or_create(language_code="fr-CH")
LocaleSynchronization.objects.get_or_create(
locale_id=locale_fr.id, sync_from_id=locale_de.id
)
locale_it, _ = Locale.objects.get_or_create(language_code="it-CH")
LocaleSynchronization.objects.get_or_create(
locale_id=locale_it.id, sync_from_id=locale_de.id
)
call_command("sync_locale_trees")
# all pages belong to 'admin' by default
Page.objects.update(owner=user)
def create_circle_basis(lp):
circle = CircleFactory(
title="Basis",
parent=lp,
description="""
Nach dem Gespräch werten sie die Analyse aus und erstellen mit den
zur Verfügung stehenden Systemen formal korrekte Lösungsvorschläge bzw.
Ausschreibungen. Je nach Komplexität der Situation ziehen sie die nötigen
Fachspezialisten bei.
""",
job_situations=[
("job_situation", "Absicherung der Familie"),
("job_situation", "Prämien einsparen"),
("job_situation", "Deckung optimieren"),
("job_situation", "Auto kaufen"),
("job_situation", "Fahrzeugwechsel"),
("job_situation", "Pensionerung inklusive Variante Frühpensionierung"),
("job_situation", "Reisen"),
],
In diesem Circle erklären wir dir, wie der Lehrgang
Versicherungsvermittler / in " aufgebaut ist. Zudem vermitteln wir dir die wichtigsten Grundlagen,
damit erfolgreich mit deinem Lernpfad starten kannst.
""".strip(),
)
LearningSequenceFactory(title="Starten", parent=circle, icon="it-icon-ls-start")
LearningUnitFactory(title="Einführung", parent=circle)
LearningContentFactory(
title="Willkommen im Lehrgang Versicherungsvermitler VBV",
parent=circle,
)
LearningUnitFactory(title="Arbeits- und Lerntechnik", parent=circle)
LearningContentFactory(
title="Mediathek",
parent=circle,
)
LearningContentFactory(
title="Luca organisiert seinen Arbeitsalltag",
parent=circle,
)
LearningContentFactory(
title="Luca legt sich seine Lernstrategie zurecht",
parent=circle,
)
LearningContentFactory(
title="Fachcheck Arbeits- und Lerntechnik",
parent=circle,
)
LearningSequenceFactory(title="Grundlagen", parent=circle, icon="it-icon-ls-watch")
LearningUnitFactory(title="Versicherung", parent=circle)
LearningContentFactory(
title="Mediathek",
parent=circle,
)
LearningContentFactory(
title="Luca startet durch",
parent=circle,
)
LearningContentFactory(
title="Fachcheck Allgemeines zu Versicherungen",
parent=circle,
)
LearningUnitFactory(title="Beratung und Verkauf", parent=circle)
LearningContentFactory(
title="Mediathek",
parent=circle,
)
LearningContentFactory(
title="Luca macht sich fit im Verkauf",
parent=circle,
)
LearningContentFactory(
title="Fachcheck Beratung und Verkauf",
parent=circle,
)
LearningSequenceFactory(title="Beenden", parent=circle, icon="it-icon-ls-end")
LearningUnitFactory(title="Jetzt kann's los gehen", parent=circle)
LearningContentFactory(
title="Lerninhalt offen",
parent=circle,
)
def create_circle_gewinnen(lp):
circle = CircleFactory(
title="Gewinnen",
parent=lp,
description="""
Versicherungsvermittlerinnen und -vermittler verfügen über
ein starkes Netzwerk, das sie gezielt pflegen und ausbauen. Sie beraten und betreuen ihre bestehenden Kundinnen und Kunden professionell und gewinnen so ihr Vertrauen. Dadurch schaffen sie die Basis für das Gewinnen
von neuen Kundinnen und Kunden. Versicherungsvermittlerinnen und -vermittler sprechen ihre bestehenden Kundinnen
und Kunden auf Weiterempfehlung an. So nutzen sie ihre
bestehenden Kontakte geschickt für das Anwerben von
Neukundinnen und -kunden.""".strip(),
goals=[
(
"goal",
"... die heutige Versicherungssituation von Privat- oder Geschäftskunden einzuschätzen.",
"... Bestehende Kunden so zu beraten, dass sie von diesen weiterempfohlen werden",
),
(
"goal",
"... deinem Kunden einen ungenügenden oder übermässigen Versicherungsschutz aufzuzeigen.",
"... Geeignete Personen wie z.B. Garagisten, Architekten, Treuhänder auf die Vermittlung / Zusammenarbeit anzusprechen",
),
(
"goal",
"... deinem Kunden zu helfen, sein Optimierungspotential voll auszuschöpfen.",
"... Verschiedene Datenquellen wie Internet, Telefonbuch, Handelszeitung, Baugesuche etc. Gezielt für die Gewinnung von Neukunden zu benützen",
),
("goal", "... deinem Kunden seine optimale Lösung aufzuzeigen"),
],
experts=[
(
"person",
{
"last_name": "Huggel",
"first_name": "Patrizia",
"email": "patrizia.huggel@example.com",
},
"goal",
"... Ein beliebiges Gespräch resp. Einen bestehenden Kontakt in die Richtung «Versicherung» zu lenken",
),
(
"goal",
"... Das Thema Risiko und Sicherheit in einem Gespräch gezielt und auf die Situation des jeweiligen Gesprächspartners bezogen einfliessen zu lassen",
),
(
"goal",
"... Im täglichen Kontakt potenzielle Kundinnen und Kunden zu erkennen",
),
],
)
LearningSequenceFactory(title="Starten", parent=circle, icon="it-icon-ls-start")
LearningUnitFactory(title="Einführung", parent=circle)
LearningContentFactory(
title="Verschaff dir einen Überblick",
parent=circle,
)
LearningSequenceFactory(title="Beobachten", parent=circle, icon="it-icon-ls-watch")
LearningUnitFactory(title="Kunden gewinnen", parent=circle)
LearningContentFactory(
title="Mediathek",
parent=circle,
)
LearningContentFactory(
title="Lerninhalt offen",
parent=circle,
)
LearningContentFactory(
title="Fachcheck Kunden gewinnen",
parent=circle,
)
LearningSequenceFactory(title="Anwenden", parent=circle, icon="it-icon-ls-watch")
LearningUnitFactory(title="Sozialer Auftritt", parent=circle)
LearningContentFactory(
title="Mediathek",
parent=circle,
)
LearningContentFactory(
title="Lerninhalt offen",
parent=circle,
)
LearningContentFactory(
title="Fachcheck Sozialer Auftritt",
parent=circle,
)
LearningSequenceFactory(title="Üben", parent=circle, icon="it-icon-ls-practice")
LearningUnitFactory(title="Sozialer Auftritt", parent=circle)
LearningContentFactory(
title="Mediathek",
parent=circle,
)
LearningContentFactory(
title="Lerninhalt offen",
parent=circle,
)
LearningSequenceFactory(title="Beenden", parent=circle, icon="it-icon-ls-end")
LearningUnitFactory(title="Circle beenden", parent=circle)
LearningContentFactory(
title="Lerninhalt offen",
parent=circle,
)
def create_circle_einstieg(lp):
circle = CircleFactory(
title="Einstieg",
parent=lp,
)
LearningSequenceFactory(title="Starten", parent=circle, icon="it-icon-ls-start")
LearningUnitFactory(title="Einführung", parent=circle)
LearningContentFactory(
title="Verschaff dir einen Überblick",
parent=circle,
contents=[
(
"video",
VideoBlockFactory(
url="https://onedrive.live.com/embed?cid=26E4A934B79DCE5E&resid=26E4A934B79DCE5E%2153350&authkey=AId6i7z_X8l2fHw",
description="In dieser Circle zeigt dir ein Fachexperte anhand von Kundensituationen, wie du erfolgreich"
"den Kundenbedarf ermitteln, analysieren, priorisieren und anschliessend zusammenfassen kannst.",
),
)
],
)
LearningSequenceFactory(title="Beobachten", parent=circle, icon="it-icon-ls-watch")
create_standard_learning_unit(
"Patrizia & Marco sichern sich ab",
parent=circle,
category_name="Einkommenssicherung",
wbt_url="/static/media/web_based_trainings/story-01-a-01-patrizia-marco-sichern-sich-ab-einstieg/scormcontent/index.html",
)
LearningSequenceFactory(title="Anwenden", parent=circle, icon="it-icon-ls-apply")
create_standard_learning_unit(
"Rafael Fasel wechselt sein Auto",
parent=circle,
category_name="Fahrzeug",
wbt_url="/static/media/web_based_trainings/training-04-a-01-rafael-fasel-wechselt-sein-auto-einstieg/scormcontent/index.html",
)
create_standard_learning_unit(
"Rafael Fasel zieht von zu Hause aus",
parent=circle,
category_name="Haushalt",
)
create_standard_learning_unit(
"Emma und Ayla campen durch Amerika",
parent=circle,
category_name="Reisen",
wbt_url="/static/media/web_based_trainings/story-06-a-01-emma-und-ayla-campen-durch-amerika-einstieg/scormcontent/index.html",
check_url="/static/media/demo_oktober/fach_check_reisen/index.html",
)
create_standard_learning_unit(
"Herr und Frau Russo planen ihre Pensionierung",
parent=circle,
category_name="Pensionierung",
)
create_standard_learning_unit(
"Familie Babic erwartet Nachwuchs",
parent=circle,
category_name="Gesundheit",
)
create_standard_learning_unit(
"Anna Fleur übernimmt den Blumenladen",
parent=circle,
category_name="KMU",
)
LearningSequenceFactory(title="Üben", parent=circle, icon="it-icon-ls-practice")
LearningUnitFactory(title="Gesprächseinstieg", parent=circle)
LearningContentFactory(
title="Mediathek",
parent=circle,
)
LearningContentFactory(
title="Der erste Eindruck zählt",
parent=circle,
)
LearningSequenceFactory(title="Beenden", parent=circle, icon="it-icon-ls-end")
LearningUnitFactory(title="Circle beenden", parent=circle)
LearningContentFactory(
title="Lerninhalt offen",
parent=circle,
)
def create_circle_analyse(lp):
circle = CircleFactory(
title="Analyse",
parent=lp,
)
LearningSequenceFactory(title="Starten", parent=circle, icon="it-icon-ls-start")
LearningUnitFactory(title="Einführung", parent=circle)
LearningContentFactory(
title="Verschaff dir einen Überblick",
parent=circle,
contents=[
(
"video",
VideoBlockFactory(
url="https://onedrive.live.com/embed?cid=26E4A934B79DCE5E&resid=26E4A934B79DCE5E%2153352&authkey=ABAdnARrD5VsIG8",
description="",
),
)
],
)
LearningSequenceFactory(title="Beobachten", parent=circle, icon="it-icon-ls-watch")
create_standard_learning_unit(
"Patrizia & Marco sichern sich ab",
parent=circle,
category_name="Einkommenssicherung",
)
LearningSequenceFactory(title="Anwenden", parent=circle, icon="it-icon-ls-apply")
create_standard_learning_unit(
"Rafael Fasel wechselt sein Auto",
parent=circle,
category_name="Fahrzeug",
wbt_url="/static/media/web_based_trainings/story-04-a-02-rafael-fasel-wechselt-sein-auto-analyse/scormcontent/index.html",
)
create_standard_learning_unit(
"Rafael Fasel zieht von zu Hause aus",
parent=circle,
category_name="Haushalt",
)
create_standard_learning_unit(
"Emma und Ayla campen durch Amerika",
parent=circle,
category_name="Reisen",
check_url="/static/media/demo_oktober/fach_check_reisen/index.html",
)
create_standard_learning_unit(
"Herr und Frau Russo planen ihre Pensionierung",
parent=circle,
category_name="Pensionierung",
)
create_standard_learning_unit(
"Familie Babic erwartet Nachwuchs",
parent=circle,
category_name="Gesundheit",
)
create_standard_learning_unit(
"Anna Fleur übernimmt den Blumenladen",
parent=circle,
category_name="KMU",
)
LearningSequenceFactory(title="Üben", parent=circle, icon="it-icon-ls-practice")
LearningUnitFactory(title="Gesprächseinstieg", parent=circle)
LearningContentFactory(
title="Mediathek",
parent=circle,
)
LearningContentFactory(
title="Lerninhalt offen",
parent=circle,
)
LearningSequenceFactory(title="Beenden", parent=circle, icon="it-icon-ls-end")
LearningUnitFactory(title="Circle beenden", parent=circle)
LearningContentFactory(
title="Lerninhalt offen",
parent=circle,
)
def create_circle_loesung(lp):
circle = CircleFactory(
title="Lösung",
parent=lp,
)
LearningSequenceFactory(title="Starten", parent=circle, icon="it-icon-ls-start")
LearningUnitFactory(title="Einführung", parent=circle)
LearningContentFactory(
title="Verschaff dir einen Überblick",
parent=circle,
)
LearningSequenceFactory(title="Beobachten", parent=circle, icon="it-icon-ls-watch")
create_standard_learning_unit(
"Patrizia & Marco sichern sich ab",
parent=circle,
category_name="Einkommenssicherung",
)
LearningSequenceFactory(title="Anwenden", parent=circle, icon="it-icon-ls-apply")
create_standard_learning_unit(
"Rafael Fasel wechselt sein Auto",
parent=circle,
category_name="Fahrzeug",
)
create_standard_learning_unit(
"Rafael Fasel zieht von zu Hause aus",
parent=circle,
category_name="Haushalt",
)
create_standard_learning_unit(
"Emma und Ayla campen durch Amerika",
parent=circle,
category_name="Reisen",
check_url="/static/media/demo_oktober/fach_check_reisen/index.html",
)
create_standard_learning_unit(
"Herr und Frau Russo planen ihre Pensionierung",
parent=circle,
category_name="Pensionierung",
)
create_standard_learning_unit(
"Familie Babic erwartet Nachwuchs",
parent=circle,
category_name="Gesundheit",
)
create_standard_learning_unit(
"Anna Fleur übernimmt den Blumenladen",
parent=circle,
category_name="KMU",
)
LearningSequenceFactory(title="Üben", parent=circle, icon="it-icon-ls-practice")
LearningUnitFactory(title="Heirat", parent=circle)
LearningContentFactory(
title="Mediathek",
parent=circle,
)
LearningContentFactory(
title="Patrizia & Marco heiraten",
parent=circle,
)
LearningContentFactory(
title="Fachcheck Heirat",
parent=circle,
)
LearningSequenceFactory(title="Beenden", parent=circle, icon="it-icon-ls-end")
LearningUnitFactory(title="Circle beenden", parent=circle)
LearningContentFactory(
title="Lerninhalt offen",
parent=circle,
)
def create_circle_abschluss(lp):
circle = CircleFactory(
title="Abschluss",
parent=lp,
)
LearningSequenceFactory(title="Starten", parent=circle, icon="it-icon-ls-start")
LearningUnitFactory(title="Einführung", parent=circle)
LearningContentFactory(
title="Verschaff dir einen Überblick",
parent=circle,
)
LearningSequenceFactory(title="Beobachten", parent=circle, icon="it-icon-ls-watch")
create_standard_learning_unit(
"Patrizia & Marco sichern sich ab",
parent=circle,
category_name="Einkommenssicherung",
)
LearningSequenceFactory(title="Anwenden", parent=circle, icon="it-icon-ls-apply")
create_standard_learning_unit(
"Rafael Fasel wechselt sein Auto",
parent=circle,
category_name="Fahrzeug",
)
create_standard_learning_unit(
"Rafael Fasel zieht von zu Hause aus",
parent=circle,
category_name="Haushalt",
)
create_standard_learning_unit(
"Emma und Ayla campen durch Amerika",
parent=circle,
category_name="Reisen",
check_url="/static/media/demo_oktober/fach_check_reisen/index.html",
)
create_standard_learning_unit(
"Herr und Frau Russo planen ihre Pensionierung",
parent=circle,
category_name="Pensionierung",
)
create_standard_learning_unit(
"Familie Babic erwartet Nachwuchs",
parent=circle,
category_name="Gesundheit",
)
create_standard_learning_unit(
"Anna Fleur übernimmt den Blumenladen",
parent=circle,
category_name="KMU",
)
LearningSequenceFactory(title="Üben", parent=circle, icon="it-icon-ls-practice")
LearningUnitFactory(title="Auswandern", parent=circle)
LearningContentFactory(
title="Mediathek",
parent=circle,
)
LearningContentFactory(
title="Emma und Ayla wandern nach Amerika aus",
parent=circle,
)
LearningContentFactory(
title="Fachcheck Auswandern",
parent=circle,
)
LearningSequenceFactory(title="Beenden", parent=circle, icon="it-icon-ls-end")
LearningUnitFactory(title="Circle beenden", parent=circle)
LearningContentFactory(
title="Lerninhalt offen",
parent=circle,
)
def create_circle_betreuen(lp):
circle = CircleFactory(
title="Abschluss",
parent=lp,
)
LearningSequenceFactory(title="Starten", parent=circle, icon="it-icon-ls-start")
LearningUnitFactory(title="Einführung", parent=circle)
LearningContentFactory(
title="Verschaff dir einen Überblick",
parent=circle,
)
LearningSequenceFactory(title="Beobachten", parent=circle, icon="it-icon-ls-watch")
create_standard_learning_unit(
"Patrizia Feller macht sich selbsständig",
parent=circle,
category_name="Selbständigkeit",
)
LearningSequenceFactory(title="Anwenden", parent=circle, icon="it-icon-ls-apply")
create_standard_learning_unit(
"Familie Feller Bonsera kaufen ein Haus",
parent=circle,
category_name="Wohneigentum",
)
create_standard_learning_unit(
"Rafael Fasel hat Ärger mit dem Vermieter",
parent=circle,
category_name="Rechtsstreitigkeiten",
)
create_standard_learning_unit(
"Familie Babic spart auf ein Ziel",
parent=circle,
category_name="Sparen",
)
create_standard_learning_unit(
"Chiara übernimmt das Haus der Eltern",
parent=circle,
category_name="Erben / Vererben",
)
LearningSequenceFactory(title="Üben", parent=circle, icon="it-icon-ls-practice")
LearningUnitFactory(title="Bauen", parent=circle)
create_standard_learning_unit(
"Blumenladen Fleur expandiert",
parent=circle,
category_name="Wohneigentum",
)
create_standard_learning_unit(
"Davide & Giulia verkaufen ihr Haus an Chiara",
parent=circle,
category_name="Wohneigentum",
)
LearningSequenceFactory(title="Beenden", parent=circle, icon="it-icon-ls-end")
LearningUnitFactory(title="Circle beenden", parent=circle)
LearningContentFactory(
title="Lerninhalt offen",
parent=circle,
)
def create_standard_learning_unit(
title, parent, category_name, wbt_url=None, check_url=None
):
LearningUnitFactory(
title=category_name,
parent=parent,
course_category=CourseCategory.objects.get(
course_id=COURSE_VERSICHERUNGSVERMITTLERIN_ID, title=category_name
),
)
LearningContentFactory(
title=f"Mediathek {category_name}",
parent=parent,
contents=[
(
"media_library",
MediaLibraryBlockFactory(
url=f"/media/versicherungsvermittlerin-media/category/{slugify(category_name)}"
),
)
],
)
if wbt_url is None:
LearningContentFactory(
title=title,
parent=parent,
)
else:
LearningContentFactory(
title=title,
parent=parent,
contents=[
(
"exercise",
ExerciseBlockFactory(url=wbt_url),
)
],
)
if check_url is None:
LearningContentFactory(
title=f"Fachcheck {category_name}",
parent=parent,
)
else:
LearningContentFactory(
title=f"Fachcheck {category_name}",
parent=parent,
contents=[
(
"test",
TestBlockFactory(url=check_url),
)
],
)
def create_circle_children(circle, title):
@ -398,148 +1007,3 @@ def create_circle_children(circle, title):
minutes=30,
contents=[("document", DocumentBlockFactory())],
)
def create_default_learning_path(user=None, skip_locales=True):
if user is None:
user = User.objects.get(username="info@iterativ.ch")
site = Site.objects.filter(is_default_site=True).first()
if not site:
site = wagtail_factories.SiteFactory(is_default_site=True)
if settings.APP_ENVIRONMENT == "development":
site.port = 8000
site.save()
# create_default_competences()
course_page = CoursePage.objects.get(course_id=COURSE_VERSICHERUNGSVERMITTLERIN_ID)
lp = LearningPathFactory(
title="Versicherungsvermittler/in",
parent=course_page,
)
TopicFactory(title="Basis", is_visible=False, parent=lp)
circle_basis = CircleFactory(
title="Basis",
parent=lp,
description="""
In diesem Circle erklären wir dir, wie der Lehrgang
Versicherungsvermittler / in " aufgebaut ist. Zudem vermitteln wir dir die wichtigsten Grundlagen,
damit erfolgreich mit deinem Lernpfad starten kannst.
""",
)
LearningSequenceFactory(
title="Starten", parent=circle_basis, icon="it-icon-ls-start"
)
LearningContentFactory(
title='Einleitung Circle "Basis"',
parent=circle_basis,
minutes=15,
contents=[
(
"video",
VideoBlockFactory(
url="https://www.youtube.com/embed/qhPIfxS2hvI",
description="In dieser Circle zeigt dir ein Fachexperte anhand von Kundensituationen, wie du erfolgreich"
"den Kundenbedarf ermitteln, analysieren, priorisieren und anschliessend zusammenfassen kannst.",
),
)
],
)
LearningSequenceFactory(title="Beenden", parent=circle_basis, icon="it-icon-ls-end")
LearningContentFactory(
title="Kompetenzprofil anschauen",
parent=circle_basis,
minutes=30,
contents=[("document", DocumentBlockFactory())],
)
LearningContentFactory(
title='Circle "Analyse" abschliessen',
parent=circle_basis,
minutes=30,
contents=[("document", DocumentBlockFactory())],
)
TopicFactory(title="Gewinnen von Kunden", parent=lp)
circle_gewinnen = CircleFactory(
title="Gewinnen",
parent=lp,
description="""
Versicherungsvermittlerinnen und -vermittler verfügen über
ein starkes Netzwerk, das sie gezielt pflegen und ausbauen. Sie beraten und betreuen ihre bestehenden Kundinnen und Kunden professionell und gewinnen so ihr Vertrauen. Dadurch schaffen sie die Basis für das Gewinnen
von neuen Kundinnen und Kunden. Versicherungsvermittlerinnen und -vermittler sprechen ihre bestehenden Kundinnen
und Kunden auf Weiterempfehlung an. So nutzen sie ihre
bestehenden Kontakte geschickt für das Anwerben von
Neukundinnen und -kunden.""",
goals=[
(
"goal",
"... Bestehende Kunden so zu beraten, dass sie von diesen weiterempfohlen werden",
),
(
"goal",
"... Geeignete Personen wie z.B. Garagisten, Architekten, Treuhänder auf die Vermittlung / Zusammenarbeit anzusprechen",
),
(
"goal",
"... Verschiedene Datenquellen wie Internet, Telefonbuch, Handelszeitung, Baugesuche etc. Gezielt für die Gewinnung von Neukunden zu benützen",
),
(
"goal",
"... Ein beliebiges Gespräch resp. Einen bestehenden Kontakt in die Richtung «Versicherung» zu lenken",
),
(
"goal",
"... Das Thema Risiko und Sicherheit in einem Gespräch gezielt und auf die Situation des jeweiligen Gesprächspartners bezogen einfliessen zu lassen",
),
(
"goal",
"... Im täglichen Kontakt potenzielle Kundinnen und Kunden zu erkennen",
),
],
)
create_circle_children(circle_gewinnen, "Gewinnen")
TopicFactory(title="Beraten der Kunden", parent=lp)
circle_einstieg = create_circle("Einstieg", lp)
create_circle_children(circle_einstieg, "Einstieg")
circle_analyse = create_circle("Analyse", lp)
create_circle_children(circle_analyse, "Analyse")
circle_analyse = create_circle("Lösung", lp)
create_circle_children(circle_analyse, "Lösung")
circle_analyse = create_circle("Abschluss", lp)
create_circle_children(circle_analyse, "Abschluss")
TopicFactory(title="Betreuen und Ausbauen des Kundenstamms", parent=lp)
circle_analyse = create_circle("Betreuen", lp)
create_circle_children(circle_analyse, "Betreuen")
TopicFactory(title="Prüfung", is_visible=True, parent=lp)
circle_analyse = create_circle("Prüfungsvorbereitung", lp)
create_circle_children(circle_analyse, "Prüfungsvorbereitung")
# locales
if not skip_locales:
locale_de = Locale.objects.get(language_code="de-CH")
locale_fr, _ = Locale.objects.get_or_create(language_code="fr-CH")
LocaleSynchronization.objects.get_or_create(
locale_id=locale_fr.id, sync_from_id=locale_de.id
)
locale_it, _ = Locale.objects.get_or_create(language_code="it-CH")
LocaleSynchronization.objects.get_or_create(
locale_id=locale_it.id, sync_from_id=locale_de.id
)
call_command("sync_locale_trees")
# all pages belong to 'admin' by default
Page.objects.update(owner=user)

View File

@ -0,0 +1,114 @@
# Generated by Django 3.2.13 on 2022-10-04 13:34
import wagtail.blocks
import wagtail.fields
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("learnpath", "0001_initial"),
]
operations = [
migrations.AlterField(
model_name="learningcontent",
name="contents",
field=wagtail.fields.StreamField(
[
(
"video",
wagtail.blocks.StructBlock(
[
("description", wagtail.blocks.TextBlock()),
("url", wagtail.blocks.URLBlock()),
]
),
),
(
"resource",
wagtail.blocks.StructBlock(
[
("description", wagtail.blocks.TextBlock()),
("url", wagtail.blocks.URLBlock()),
]
),
),
(
"exercise",
wagtail.blocks.StructBlock(
[
("description", wagtail.blocks.TextBlock()),
("url", wagtail.blocks.URLBlock()),
]
),
),
(
"online_training",
wagtail.blocks.StructBlock(
[
("description", wagtail.blocks.TextBlock()),
("url", wagtail.blocks.URLBlock()),
]
),
),
(
"media_library",
wagtail.blocks.StructBlock(
[
("description", wagtail.blocks.TextBlock()),
("url", wagtail.blocks.URLBlock()),
]
),
),
(
"document",
wagtail.blocks.StructBlock(
[
("description", wagtail.blocks.TextBlock()),
("url", wagtail.blocks.URLBlock()),
]
),
),
(
"test",
wagtail.blocks.StructBlock(
[
("description", wagtail.blocks.TextBlock()),
("url", wagtail.blocks.URLBlock()),
]
),
),
(
"book",
wagtail.blocks.StructBlock(
[
("description", wagtail.blocks.TextBlock()),
("url", wagtail.blocks.URLBlock()),
]
),
),
(
"assignment",
wagtail.blocks.StructBlock(
[
("description", wagtail.blocks.TextBlock()),
("url", wagtail.blocks.URLBlock()),
]
),
),
(
"placeholder",
wagtail.blocks.StructBlock(
[
("description", wagtail.blocks.TextBlock()),
("url", wagtail.blocks.URLBlock()),
]
),
),
],
use_json_field=None,
),
),
]

View File

@ -0,0 +1,114 @@
# Generated by Django 3.2.13 on 2022-10-05 10:06
import wagtail.blocks
import wagtail.fields
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("learnpath", "0002_alter_learningcontent_contents"),
]
operations = [
migrations.AlterField(
model_name="learningcontent",
name="contents",
field=wagtail.fields.StreamField(
[
(
"video",
wagtail.blocks.StructBlock(
[
("description", wagtail.blocks.TextBlock()),
("url", wagtail.blocks.TextBlock()),
]
),
),
(
"resource",
wagtail.blocks.StructBlock(
[
("description", wagtail.blocks.TextBlock()),
("url", wagtail.blocks.TextBlock()),
]
),
),
(
"exercise",
wagtail.blocks.StructBlock(
[
("description", wagtail.blocks.TextBlock()),
("url", wagtail.blocks.TextBlock()),
]
),
),
(
"online_training",
wagtail.blocks.StructBlock(
[
("description", wagtail.blocks.TextBlock()),
("url", wagtail.blocks.TextBlock()),
]
),
),
(
"media_library",
wagtail.blocks.StructBlock(
[
("description", wagtail.blocks.TextBlock()),
("url", wagtail.blocks.TextBlock()),
]
),
),
(
"document",
wagtail.blocks.StructBlock(
[
("description", wagtail.blocks.TextBlock()),
("url", wagtail.blocks.TextBlock()),
]
),
),
(
"test",
wagtail.blocks.StructBlock(
[
("description", wagtail.blocks.TextBlock()),
("url", wagtail.blocks.TextBlock()),
]
),
),
(
"book",
wagtail.blocks.StructBlock(
[
("description", wagtail.blocks.TextBlock()),
("url", wagtail.blocks.TextBlock()),
]
),
),
(
"assignment",
wagtail.blocks.StructBlock(
[
("description", wagtail.blocks.TextBlock()),
("url", wagtail.blocks.TextBlock()),
]
),
),
(
"placeholder",
wagtail.blocks.StructBlock(
[
("description", wagtail.blocks.TextBlock()),
("url", wagtail.blocks.TextBlock()),
]
),
),
],
use_json_field=None,
),
),
]

View File

@ -16,6 +16,7 @@ from vbv_lernwelt.learnpath.models_learning_unit_content import (
ExerciseBlock,
MediaLibraryBlock,
OnlineTrainingBlock,
PlaceholderBlock,
ResourceBlock,
TestBlock,
VideoBlock,
@ -86,6 +87,9 @@ class Topic(Page):
],
)
def get_admin_display_title(self):
return f"Thema: {self.draft_title}"
class Meta:
verbose_name = "Topic"
@ -197,6 +201,9 @@ class LearningSequence(Page):
<span style="margin-left: 8px;">{self.draft_title}</span>
</span>"""
def get_admin_display_title(self):
return f"LS: {self.draft_title}"
def full_clean(self, *args, **kwargs):
self.slug = find_slug_with_parent_prefix(self, "ls")
super(LearningSequence, self).full_clean(*args, **kwargs)
@ -246,6 +253,9 @@ class LearningUnit(Page):
short_slug = self.slug.replace(f"{self.get_parent().slug}-lu-", "")
return f"{self.get_parent().specific.get_frontend_url()}/evaluate/{short_slug}"
def get_admin_display_title(self):
return f"LE: {self.draft_title}"
@classmethod
def get_serializer_class(cls):
from vbv_lernwelt.learnpath.serializers import LearningUnitSerializer
@ -272,6 +282,7 @@ class LearningContent(Page):
("test", TestBlock()),
("book", BookBlock()),
("assignment", AssignmentBlock()),
("placeholder", PlaceholderBlock()),
]
contents = StreamField(

View File

@ -3,7 +3,7 @@ from wagtail import blocks
class AssignmentBlock(blocks.StructBlock):
description = blocks.TextBlock()
url = blocks.URLBlock()
url = blocks.TextBlock()
class Meta:
icon = "media"
@ -11,7 +11,7 @@ class AssignmentBlock(blocks.StructBlock):
class BookBlock(blocks.StructBlock):
description = blocks.TextBlock()
url = blocks.URLBlock()
url = blocks.TextBlock()
class Meta:
icon = "media"
@ -19,7 +19,15 @@ class BookBlock(blocks.StructBlock):
class DocumentBlock(blocks.StructBlock):
description = blocks.TextBlock()
url = blocks.URLBlock()
url = blocks.TextBlock()
class Meta:
icon = "media"
class PlaceholderBlock(blocks.StructBlock):
description = blocks.TextBlock()
url = blocks.TextBlock()
class Meta:
icon = "media"
@ -27,7 +35,7 @@ class DocumentBlock(blocks.StructBlock):
class ExerciseBlock(blocks.StructBlock):
description = blocks.TextBlock()
url = blocks.URLBlock()
url = blocks.TextBlock()
class Meta:
icon = "media"
@ -35,7 +43,7 @@ class ExerciseBlock(blocks.StructBlock):
class MediaLibraryBlock(blocks.StructBlock):
description = blocks.TextBlock()
url = blocks.URLBlock()
url = blocks.TextBlock()
class Meta:
icon = "media"
@ -43,7 +51,7 @@ class MediaLibraryBlock(blocks.StructBlock):
class OnlineTrainingBlock(blocks.StructBlock):
description = blocks.TextBlock()
url = blocks.URLBlock()
url = blocks.TextBlock()
class Meta:
icon = "media"
@ -51,7 +59,7 @@ class OnlineTrainingBlock(blocks.StructBlock):
class ResourceBlock(blocks.StructBlock):
description = blocks.TextBlock()
url = blocks.URLBlock()
url = blocks.TextBlock()
class Meta:
icon = "media"
@ -59,7 +67,7 @@ class ResourceBlock(blocks.StructBlock):
class TestBlock(blocks.StructBlock):
description = blocks.TextBlock()
url = blocks.URLBlock()
url = blocks.TextBlock()
class Meta:
icon = "media"
@ -68,7 +76,7 @@ class TestBlock(blocks.StructBlock):
class VideoBlock(blocks.StructBlock):
# TODO: Possible video Types for the user, upload file, add URL
description = blocks.TextBlock()
url = blocks.URLBlock()
url = blocks.TextBlock()
class Meta:
icon = "media"

View File

@ -15,6 +15,7 @@ from vbv_lernwelt.learnpath.models_learning_unit_content import (
ExerciseBlock,
MediaLibraryBlock,
OnlineTrainingBlock,
PlaceholderBlock,
ResourceBlock,
TestBlock,
VideoBlock,
@ -36,34 +37,6 @@ class TopicFactory(wagtail_factories.PageFactory):
model = Topic
class CircleFactory(wagtail_factories.PageFactory):
title = "Gewinnen"
class Meta:
model = Circle
class LearningSequenceFactory(wagtail_factories.PageFactory):
title = "Grundlagen"
class Meta:
model = LearningSequence
class LearningUnitFactory(wagtail_factories.PageFactory):
title = "Lerneinheit"
class Meta:
model = LearningUnit
class LearningContentFactory(wagtail_factories.PageFactory):
title = "Lerninhalt"
class Meta:
model = LearningContent
class VideoBlockFactory(wagtail_factories.StructBlockFactory):
url = "https://www.youtube.com/embed/qhPIfxS2hvI"
description = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam"
@ -93,6 +66,13 @@ class DocumentBlockFactory(wagtail_factories.StructBlockFactory):
model = DocumentBlock
class PlaceholderBlockFactory(wagtail_factories.StructBlockFactory):
description = "Platzhalter"
class Meta:
model = PlaceholderBlock
class ExerciseBlockFactory(wagtail_factories.StructBlockFactory):
description = "Beispiel Übung"
@ -123,7 +103,58 @@ class ResourceBlockFactory(wagtail_factories.StructBlockFactory):
class MediaLibraryBlockFactory(wagtail_factories.StructBlockFactory):
description = "Beispiel Mediathekeninhalt"
description = "Sie erreichen die Mediathek mit einem Klick auf den unteren Link"
class Meta:
model = MediaLibraryBlock
class CircleFactory(wagtail_factories.PageFactory):
title = "Analyse"
description = """
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor.
Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes,
nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu,
pretium quis, sem. Nulla consequat massa quis enim. Donec.
""".strip()
job_situations = [("job_situation", f"Job Situation {x + 1}") for x in range(7)]
goals = [
("goal", f"... hier ein Beispieltext für ein Ziel {x + 1}") for x in range(3)
]
experts = [
(
"person",
{
"last_name": "Mustermann",
"first_name": "Patrizia",
"email": "patrizia.mustermann@example.com",
},
),
]
class Meta:
model = Circle
class LearningSequenceFactory(wagtail_factories.PageFactory):
title = "Anwenden"
icon = "it-icon-ls-apply"
class Meta:
model = LearningSequence
class LearningUnitFactory(wagtail_factories.PageFactory):
title = "Fahrzeug"
class Meta:
model = LearningUnit
class LearningContentFactory(wagtail_factories.PageFactory):
title = "Platzhalter Inhalt"
contents = [("placeholder", PlaceholderBlockFactory())]
minutes = 15
class Meta:
model = LearningContent

View File

@ -2,7 +2,7 @@ from wagtail import blocks
class MediaLibraryContentBlock(blocks.StructBlock):
title = blocks.TextBlock(blank=False, null=False)
title = blocks.TextBlock()
description = blocks.TextBlock(default="", required=False)
icon_url = blocks.TextBlock(default="", required=False)
link_display_text = blocks.CharBlock(max_length=255, default="Link öffnen")
@ -35,6 +35,7 @@ class MediaContentCollection(blocks.StructBlock):
"""
title = blocks.TextBlock()
description = blocks.TextBlock(default="", required=False)
contents = blocks.StreamBlock(
[
("learn_media", MediaLibraryContentBlock()),

View File

@ -115,13 +115,32 @@ die der Fahrzeugbesitzer und die Fahrzeugbesitzerin in einem grösseren Schadenf
),
create_media_collection(
title="Verankerung im Lernpfad",
description="Anhand der Story von Rafael Fasel und seinem Ford Mustang lernst du in diesem berufstypischem Handlungsfeld alles rund um Motorfahrzeugversicherungen, wie man sein Auto optimal schützen kann, wie du vorgehst bei einem Fahrzeugwechsel, welche Aspekte du bei einer Offerte beachten musst und wie du dem Kunden die Lösung präsentierst.",
contents=[
create_internal_link_block(
InternalLinkBlockFactory(
title="Rafael kauft einen Ford Mustang",
description="Anhand der Story von Rafael Fasel und seinem Ford Mustang lernst du in diesem berufstypischem Handlungsfeld alles rund um Motorfahrzeugversicherungen, wie man sein Auto optimal schützen kann, wie du vorgehst bei einem Fahrzeugwechsel, welche Aspekte du bei einer Offerte beachten musst und wie du dem Kunden die Lösung präsentierst.",
title="Circle: Einstieg Lernsequenz: Anwenden",
url="/learn/versicherungsvermittlerin-lp/einstieg#lu-fahrzeug",
)
)
),
create_internal_link_block(
InternalLinkBlockFactory(
title="Circle: Analyse Lernsequenz: Anwenden",
url="/learn/versicherungsvermittlerin-lp/analyse#lu-fahrzeug",
)
),
create_internal_link_block(
InternalLinkBlockFactory(
title="Circle: Lösung Lernsequenz: Anwenden",
url="/learn/versicherungsvermittlerin-lp/lösung#lu-fahrzeug",
)
),
create_internal_link_block(
InternalLinkBlockFactory(
title="Circle: Abschluss Lernsequenz: Anwenden",
url="/learn/versicherungsvermittlerin-lp/abschluss#lu-fahrzeug",
)
),
],
),
create_media_collection(
@ -198,13 +217,32 @@ Diese können negative Folgen verschiedener Art nach sich ziehen, darunter recht
),
create_media_collection(
title="Verankerung im Lernpfad",
description="Begleite Emma Durand und Ayla Yilmaz bei den Vorbereitungen auf ihre grosse Reise durch Amerika und lerne dabei, welche Risiken durch welche Versicherungen abgedeckt werden können.",
contents=[
create_internal_link_block(
InternalLinkBlockFactory(
title="Emma und Ayla campen durch Amerika",
description="Begleite Emma Durand und Ayla Yilmaz bei den Vorbereitungen auf ihre grosse Reise durch Amerika und lerne dabei, welche Risiken durch welche Versicherungen abgedeckt werden können.",
title="Circle: Einstieg Lernsequenz: Anwenden",
url="/learn/versicherungsvermittlerin-lp/einstieg#lu-reisen",
)
)
),
create_internal_link_block(
InternalLinkBlockFactory(
title="Circle: Analyse Lernsequenz: Anwenden",
url="/learn/versicherungsvermittlerin-lp/analyse#lu-reisen",
)
),
create_internal_link_block(
InternalLinkBlockFactory(
title="Circle: Lösung Lernsequenz: Anwenden",
url="/learn/versicherungsvermittlerin-lp/lösung#lu-reisen",
)
),
create_internal_link_block(
InternalLinkBlockFactory(
title="Circle: Abschluss Lernsequenz: Anwenden",
url="/learn/versicherungsvermittlerin-lp/abschluss#lu-reisen",
)
),
],
),
create_media_collection(

View File

@ -0,0 +1,262 @@
# Generated by Django 3.2.13 on 2022-10-05 12:18
import wagtail.blocks
import wagtail.fields
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("media_library", "0001_initial"),
]
operations = [
migrations.AlterField(
model_name="mediacategorypage",
name="body",
field=wagtail.fields.StreamField(
[
(
"content_collection",
wagtail.blocks.StructBlock(
[
("title", wagtail.blocks.TextBlock()),
(
"description",
wagtail.blocks.TextBlock(
default="", required=False
),
),
(
"contents",
wagtail.blocks.StreamBlock(
[
(
"learn_media",
wagtail.blocks.StructBlock(
[
(
"title",
wagtail.blocks.TextBlock(),
),
(
"description",
wagtail.blocks.TextBlock(
default="",
required=False,
),
),
(
"icon_url",
wagtail.blocks.TextBlock(
default="",
required=False,
),
),
(
"link_display_text",
wagtail.blocks.CharBlock(
default="Link öffnen",
max_length=255,
),
),
(
"url",
wagtail.blocks.TextBlock(
default="",
required=False,
),
),
(
"open_window",
wagtail.blocks.BooleanBlock(
default=False
),
),
(
"page",
wagtail.blocks.PageChooserBlock(
page_type=[
"learnpath.LearningContent"
],
required=False,
),
),
]
),
),
(
"external_link",
wagtail.blocks.StructBlock(
[
(
"title",
wagtail.blocks.TextBlock(),
),
(
"description",
wagtail.blocks.TextBlock(
default="",
required=False,
),
),
(
"icon_url",
wagtail.blocks.TextBlock(
default="",
required=False,
),
),
(
"link_display_text",
wagtail.blocks.CharBlock(
default="Link öffnen",
max_length=255,
),
),
(
"url",
wagtail.blocks.TextBlock(
default="",
required=False,
),
),
(
"open_window",
wagtail.blocks.BooleanBlock(
default=False
),
),
(
"page",
wagtail.blocks.PageChooserBlock(
page_type=[
"learnpath.LearningContent"
],
required=False,
),
),
]
),
),
(
"internal_link",
wagtail.blocks.StructBlock(
[
(
"title",
wagtail.blocks.TextBlock(),
),
(
"description",
wagtail.blocks.TextBlock(
default="",
required=False,
),
),
(
"icon_url",
wagtail.blocks.TextBlock(
default="",
required=False,
),
),
(
"link_display_text",
wagtail.blocks.CharBlock(
default="Link öffnen",
max_length=255,
),
),
(
"url",
wagtail.blocks.TextBlock(
default="",
required=False,
),
),
(
"open_window",
wagtail.blocks.BooleanBlock(
default=False
),
),
(
"page",
wagtail.blocks.PageChooserBlock(
page_type=[
"learnpath.LearningContent"
],
required=False,
),
),
]
),
),
(
"relative_link",
wagtail.blocks.StructBlock(
[
(
"title",
wagtail.blocks.TextBlock(),
),
(
"description",
wagtail.blocks.TextBlock(
default="",
required=False,
),
),
(
"icon_url",
wagtail.blocks.TextBlock(
default="",
required=False,
),
),
(
"link_display_text",
wagtail.blocks.CharBlock(
default="Link öffnen",
max_length=255,
),
),
(
"url",
wagtail.blocks.TextBlock(
default="",
required=False,
),
),
(
"open_window",
wagtail.blocks.BooleanBlock(
default=False
),
),
(
"page",
wagtail.blocks.PageChooserBlock(
page_type=[
"learnpath.LearningContent"
],
required=False,
),
),
]
),
),
]
),
),
]
),
)
],
null=True,
use_json_field=True,
),
),
]

View File

@ -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/einleitung-circle-basis"
url = "/learn/versicherungsvermittlerin-lp/basis"
# TODO: page = blocks.PageChooserBlock mit Titel etc
@ -100,7 +100,7 @@ class RelativeLinkBlockFactory(wagtail_factories.StructBlockFactory):
model = RelativeLinkBlock
title = "Platzhalter Querverweis"
description = "Lernmedium: Verkehrsrechtsschutz Buch «Sach- und Vermögensversicherungen/Kapitel 12.3»"
description = "Handlungsfeld"
link_display_text = "Handlungsfeld anzeigen"
icon_url = "/static/icons/demo/icon-hf-reisen.svg"
url = "/media/versicherungsvermittlerin-media/category/fahrzeug"
@ -117,11 +117,11 @@ def create_relative_link_block(link_block=None):
}
def create_media_collection(title, contents=None):
def create_media_collection(title, contents=None, description=None):
if contents is None:
contents = []
return {
result = {
"id": str(uuid.uuid4()),
"type": "content_collection",
"value": {
@ -130,6 +130,11 @@ def create_media_collection(title, contents=None):
},
}
if description:
result["value"]["description"] = description
return result
def create_document_collection(document_ids=None):
if document_ids is None:
@ -175,7 +180,7 @@ Nulla consequat massa quis enim. Donec.
contents=[create_external_link_block() for _ in range(4)],
),
create_media_collection(
title="Links",
title="Verankerung im Lernpfad",
contents=[create_internal_link_block() for _ in range(3)],
),
create_media_collection(

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB