From 3e270e97ffe8dcd172d6785dbdd43f37a358f75f Mon Sep 17 00:00:00 2001 From: Christian Cueni Date: Thu, 15 Feb 2024 12:58:41 +0100 Subject: [PATCH 1/7] Add country ordering --- .../api/tests/test_entities_api.py | 50 ++++++++++++++++++- server/vbv_lernwelt/core/admin.py | 1 + .../core/migrations/0007_country_order_id.py | 17 +++++++ server/vbv_lernwelt/core/models.py | 3 +- 4 files changed, 68 insertions(+), 3 deletions(-) create mode 100644 server/vbv_lernwelt/core/migrations/0007_country_order_id.py diff --git a/server/vbv_lernwelt/api/tests/test_entities_api.py b/server/vbv_lernwelt/api/tests/test_entities_api.py index 3ca843fc..ba1d0f9f 100644 --- a/server/vbv_lernwelt/api/tests/test_entities_api.py +++ b/server/vbv_lernwelt/api/tests/test_entities_api.py @@ -3,7 +3,7 @@ from rest_framework import status from rest_framework.test import APITestCase from vbv_lernwelt.core.model_utils import add_countries, add_organisations -from vbv_lernwelt.core.models import Organisation, User +from vbv_lernwelt.core.models import Country, Organisation, User class EntitiesViewTest(APITestCase): @@ -15,7 +15,7 @@ class EntitiesViewTest(APITestCase): add_organisations() add_countries() - def test_list_entities(self) -> None: + def test_list_organisation_entities(self) -> None: # It seems that different locales handle ordering differently (especially with lower case letters) # As such we delete entries that start with lower case letters Organisation.objects.filter(organisation_id__in=[1, 2, 3]).delete() @@ -51,3 +51,49 @@ class EntitiesViewTest(APITestCase): "name": "Afghanistan", }, ) + + def test_list_country_entities_ordered_by_country_id(self) -> None: + # GIVEN + url = reverse("list_entities") + + first_country = Country.objects.get(country_id=1) + + # WHEN + response = self.client.get(url) + + # THEN + self.assertEqual(response.status_code, status.HTTP_200_OK) + + countries = response.data["countries"] + + self.assertEqual( + countries[0], + { + "id": first_country.country_id, + "name": first_country.name_de, + }, + ) + + def test_list_country_entities_ordered_by_order_id(self) -> None: + # GIVEN + url = reverse("list_entities") + + switzerland = Country.objects.get(name_de="Schweiz") + switzerland.order_id = 1 + switzerland.save() + + # WHEN + response = self.client.get(url) + + # THEN + self.assertEqual(response.status_code, status.HTTP_200_OK) + + countries = response.data["countries"] + + self.assertEqual( + countries[0], + { + "id": switzerland.country_id, + "name": switzerland.name_de, + }, + ) diff --git a/server/vbv_lernwelt/core/admin.py b/server/vbv_lernwelt/core/admin.py index d5a98ca1..bb09bea4 100644 --- a/server/vbv_lernwelt/core/admin.py +++ b/server/vbv_lernwelt/core/admin.py @@ -122,6 +122,7 @@ class OrganisationAdmin(admin.ModelAdmin): @admin.register(Country) class CountryAdmin(admin.ModelAdmin): list_display = ( + "order_id", "country_id", "name_de", "name_fr", diff --git a/server/vbv_lernwelt/core/migrations/0007_country_order_id.py b/server/vbv_lernwelt/core/migrations/0007_country_order_id.py new file mode 100644 index 00000000..a4f8be73 --- /dev/null +++ b/server/vbv_lernwelt/core/migrations/0007_country_order_id.py @@ -0,0 +1,17 @@ +# Generated by Django 3.2.20 on 2024-02-15 10:38 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("core", "0006_auto_20240125_0915"), + ] + + operations = [ + migrations.AddField( + model_name="country", + name="order_id", + field=models.PositiveIntegerField(default=20), + ), + ] diff --git a/server/vbv_lernwelt/core/models.py b/server/vbv_lernwelt/core/models.py index 1221dee3..dcfd5927 100644 --- a/server/vbv_lernwelt/core/models.py +++ b/server/vbv_lernwelt/core/models.py @@ -26,6 +26,7 @@ class Country(models.Model): name_de = models.CharField(max_length=255) name_fr = models.CharField(max_length=255) name_it = models.CharField(max_length=255) + order_id = models.PositiveIntegerField(default=10) def __str__(self): return f"{self.name_de} ({self.country_id})" @@ -33,7 +34,7 @@ class Country(models.Model): class Meta: verbose_name = "Country" verbose_name_plural = "Countries" - ordering = ["country_id"] + ordering = ["order_id", "country_id"] class User(AbstractUser): From c180fd4406f4b773b452b751cc22ed0161c3da69 Mon Sep 17 00:00:00 2001 From: Reto Aebersold Date: Mon, 19 Feb 2024 13:35:55 +0100 Subject: [PATCH 2/7] feat: circle status cleanup --- .../components/circle/CompletionStatus.vue | 32 ++++ .../circlePage/LearningSequence.vue | 137 +++++++----------- client/src/services/circle.ts | 31 ++-- ...icon-lc-competence-certificate-checked.svg | 23 +-- 4 files changed, 107 insertions(+), 116 deletions(-) create mode 100644 client/src/components/circle/CompletionStatus.vue diff --git a/client/src/components/circle/CompletionStatus.vue b/client/src/components/circle/CompletionStatus.vue new file mode 100644 index 00000000..c75781e4 --- /dev/null +++ b/client/src/components/circle/CompletionStatus.vue @@ -0,0 +1,32 @@ + + + diff --git a/client/src/pages/learningPath/circlePage/LearningSequence.vue b/client/src/pages/learningPath/circlePage/LearningSequence.vue index 2457c591..304cbd3c 100644 --- a/client/src/pages/learningPath/circlePage/LearningSequence.vue +++ b/client/src/pages/learningPath/circlePage/LearningSequence.vue @@ -4,28 +4,24 @@ import { showIcon } from "@/pages/learningPath/circlePage/learningSequenceUtils" import { useCircleStore } from "@/stores/circle"; import type { CircleType, - CourseCompletionStatus, LearningContent, LearningContentAssignment, LearningContentEdoniqTest, - LearningContentWithCompletion, LearningSequence, } from "@/types"; import type { Ref } from "vue"; import { computed } from "vue"; -import { - itCheckboxDefaultIconCheckedTailwindClass, - itCheckboxDefaultIconUncheckedTailwindClass, -} from "@/constants"; -import ItCheckbox from "@/components/ui/ItCheckbox.vue"; + import { allFinishedInLearningSequence, - calcSelfEvaluationStatus, circleFlatLearningContents, + performanceCriteriaHasStatus, + performanceCriteriaStatusCount, someFinishedInLearningSequence, } from "@/services/circle"; -import { useCourseDataWithCompletion } from "@/composables"; + import { findLastIndex } from "lodash"; +import CompletionStatus from "@/components/circle/CompletionStatus.vue"; type Props = { courseSlug: string; @@ -41,16 +37,6 @@ const props = withDefaults(defineProps(), { const circleStore = useCircleStore(); -const lpQueryResult = useCourseDataWithCompletion(props.courseSlug); - -function toggleCompleted(learningContent: LearningContentWithCompletion) { - let completionStatus: CourseCompletionStatus = "SUCCESS"; - if (learningContent.completion_status === "SUCCESS") { - completionStatus = "FAIL"; - } - lpQueryResult.markCompletion(learningContent, completionStatus); -} - const someFinished = computed(() => { if (props.learningSequence) { return someFinishedInLearningSequence(props.learningSequence); @@ -116,20 +102,6 @@ function belongsToCompetenceCertificate(lc: LearningContent) { type LearninContentWithCompetenceCertificate = | LearningContentAssignment | LearningContentEdoniqTest; - -function checkboxIconCheckedTailwindClass(lc: LearningContent) { - if (belongsToCompetenceCertificate(lc)) { - return "bg-[url(/static/icons/icon-lc-competence-certificate-checked.svg)]"; - } - return itCheckboxDefaultIconCheckedTailwindClass; -} - -function checkboxIconUncheckedTailwindClass(lc: LearningContent) { - if (belongsToCompetenceCertificate(lc)) { - return "bg-[url(/static/icons/icon-lc-competence-certificate.svg)]"; - } - return itCheckboxDefaultIconUncheckedTailwindClass; -}