Use circle filter on competence page
This commit is contained in:
parent
cf873e6f23
commit
64b5c5a825
|
|
@ -34,12 +34,16 @@ const togglePerformanceCriteria = () => {
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<ComptenceProgress
|
<ComptenceProgress
|
||||||
:status-count="competenceStore.calcStatusCount(competence.children)"
|
:status-count="
|
||||||
|
competenceStore.calcStatusCount(
|
||||||
|
competenceStore.criteriaByCompetence(competence)
|
||||||
|
)
|
||||||
|
"
|
||||||
></ComptenceProgress>
|
></ComptenceProgress>
|
||||||
</div>
|
</div>
|
||||||
<ul v-if="isOpen">
|
<ul v-if="isOpen">
|
||||||
<li
|
<li
|
||||||
v-for="performanceCriteria in competence.children"
|
v-for="performanceCriteria in competenceStore.criteriaByCompetence(competence)"
|
||||||
:key="performanceCriteria.id"
|
:key="performanceCriteria.id"
|
||||||
class="mb-4 pb-4 border-b border-gray-500"
|
class="mb-4 pb-4 border-b border-gray-500"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import CompetenceProgress from "@/components/competences/CompetenceProgress.vue";
|
import CompetenceProgress from "@/components/competences/CompetenceProgress.vue";
|
||||||
import PerformanceCriteriaRow from "@/components/competences/PerformanceCriteriaRow.vue";
|
import PerformanceCriteriaRow from "@/components/competences/PerformanceCriteriaRow.vue";
|
||||||
|
import ItDropdownSelect from "@/components/ui/ItDropdownSelect.vue";
|
||||||
import { useCompetenceStore } from "@/stores/competence";
|
import { useCompetenceStore } from "@/stores/competence";
|
||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
import * as log from "loglevel";
|
import * as log from "loglevel";
|
||||||
|
|
@ -19,22 +20,26 @@ const failedCriteria = computed(() => {
|
||||||
});
|
});
|
||||||
|
|
||||||
const lastUpdatedCompetences = computed(() => {
|
const lastUpdatedCompetences = computed(() => {
|
||||||
if (competenceStore.competenceProfilePage?.children.length) {
|
return _.orderBy(
|
||||||
return _.orderBy(
|
competenceStore.competences,
|
||||||
competenceStore.competenceProfilePage.children,
|
[
|
||||||
[
|
(competence) => {
|
||||||
(competence) => {
|
let criteria = competence.children;
|
||||||
return (
|
if (competenceStore.selectedCircle.id != "all") {
|
||||||
_.maxBy(competence.children, "completion_status_updated_at")
|
criteria = criteria.filter((criteria) => {
|
||||||
?.completion_status_updated_at || ""
|
return (
|
||||||
);
|
criteria.circle.translation_key === competenceStore.selectedCircle.id
|
||||||
},
|
);
|
||||||
],
|
});
|
||||||
["desc"]
|
}
|
||||||
).slice(0, 3);
|
return (
|
||||||
}
|
_.maxBy(criteria, "completion_status_updated_at")
|
||||||
|
?.completion_status_updated_at || ""
|
||||||
return [];
|
);
|
||||||
|
},
|
||||||
|
],
|
||||||
|
["desc"]
|
||||||
|
).slice(0, 3);
|
||||||
});
|
});
|
||||||
|
|
||||||
const countStatus = computed(() => {
|
const countStatus = computed(() => {
|
||||||
|
|
@ -49,9 +54,10 @@ const countStatus = computed(() => {
|
||||||
class="flex flex-col lg:flex-row items-center justify-between mb-10"
|
class="flex flex-col lg:flex-row items-center justify-between mb-10"
|
||||||
>
|
>
|
||||||
<h1>Kompetenzprofil</h1>
|
<h1>Kompetenzprofil</h1>
|
||||||
<!-- <ItDropdownSelect-->
|
<ItDropdownSelect
|
||||||
<!-- v-model="dropdownSelected"-->
|
v-model="competenceStore.selectedCircle"
|
||||||
<!-- :items="mediaStore.availableLearningPaths"></ItDropdownSelect>-->
|
:items="competenceStore.availableCircles"
|
||||||
|
></ItDropdownSelect>
|
||||||
</div>
|
</div>
|
||||||
<div class="bg-white p-8 mb-8">
|
<div class="bg-white p-8 mb-8">
|
||||||
<div>
|
<div>
|
||||||
|
|
@ -66,7 +72,11 @@ const countStatus = computed(() => {
|
||||||
{{ competence.competence_id }} {{ competence.title }}
|
{{ competence.competence_id }} {{ competence.title }}
|
||||||
</p>
|
</p>
|
||||||
<CompetenceProgress
|
<CompetenceProgress
|
||||||
:status-count="competenceStore.calcStatusCount(competence.children)"
|
:status-count="
|
||||||
|
competenceStore.calcStatusCount(
|
||||||
|
competenceStore.criteriaByCompetence(competence)
|
||||||
|
)
|
||||||
|
"
|
||||||
></CompetenceProgress>
|
></CompetenceProgress>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import CompetenceDetail from "@/components/competences/CompetenceDetail.vue";
|
import CompetenceDetail from "@/components/competences/CompetenceDetail.vue";
|
||||||
|
import ItDropdownSelect from "@/components/ui/ItDropdownSelect.vue";
|
||||||
import { useCompetenceStore } from "@/stores/competence";
|
import { useCompetenceStore } from "@/stores/competence";
|
||||||
import * as log from "loglevel";
|
import * as log from "loglevel";
|
||||||
|
|
||||||
|
|
@ -21,13 +22,14 @@ const competenceStore = useCompetenceStore();
|
||||||
</nav>
|
</nav>
|
||||||
<div class="flex flex-col lg:flex-row items-center justify-between mb-10">
|
<div class="flex flex-col lg:flex-row items-center justify-between mb-10">
|
||||||
<h1>Kompetenzen</h1>
|
<h1>Kompetenzen</h1>
|
||||||
<!-- <ItDropdownSelect-->
|
<ItDropdownSelect
|
||||||
<!-- v-model="dropdownSelected"-->
|
v-model="competenceStore.selectedCircle"
|
||||||
<!-- :items="mediaStore.availableLearningPaths"></ItDropdownSelect>-->
|
:items="competenceStore.availableCircles"
|
||||||
|
></ItDropdownSelect>
|
||||||
</div>
|
</div>
|
||||||
<ul v-if="competenceStore.competenceProfilePage">
|
<ul v-if="competenceStore.competenceProfilePage">
|
||||||
<li
|
<li
|
||||||
v-for="competence in competenceStore.competenceProfilePage.children"
|
v-for="competence in competenceStore.competences"
|
||||||
:key="competence.id"
|
:key="competence.id"
|
||||||
class="bg-white p-8 mb-8"
|
class="bg-white p-8 mb-8"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { default as PerformanceCriteriaRow } from "@/components/competences/PerformanceCriteriaRow.vue";
|
import { default as PerformanceCriteriaRow } from "@/components/competences/PerformanceCriteriaRow.vue";
|
||||||
|
import ItDropdownSelect from "@/components/ui/ItDropdownSelect.vue";
|
||||||
import { useCompetenceStore } from "@/stores/competence";
|
import { useCompetenceStore } from "@/stores/competence";
|
||||||
import type { CourseCompletionStatus } from "@/types";
|
import type { CourseCompletionStatus } from "@/types";
|
||||||
import * as log from "loglevel";
|
import * as log from "loglevel";
|
||||||
|
|
@ -31,9 +32,10 @@ const shownCriteria = computed(() => {
|
||||||
</nav>
|
</nav>
|
||||||
<div class="flex flex-col lg:flex-row items-center justify-between mb-10">
|
<div class="flex flex-col lg:flex-row items-center justify-between mb-10">
|
||||||
<h1>Einschätzungen</h1>
|
<h1>Einschätzungen</h1>
|
||||||
<!-- <ItDropdownSelect-->
|
<ItDropdownSelect
|
||||||
<!-- v-model="dropdownSelected"-->
|
v-model="competenceStore.selectedCircle"
|
||||||
<!-- :items="mediaStore.availableLearningPaths"></ItDropdownSelect>-->
|
:items="competenceStore.availableCircles"
|
||||||
|
></ItDropdownSelect>
|
||||||
</div>
|
</div>
|
||||||
<div class="bg-white p-8">
|
<div class="bg-white p-8">
|
||||||
<div
|
<div
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,18 @@
|
||||||
import { itGet } from "@/fetchHelpers";
|
import { itGet } from "@/fetchHelpers";
|
||||||
import { useCompletionStore } from "@/stores/completion";
|
import { useCompletionStore } from "@/stores/completion";
|
||||||
import type { CompetenceProfilePage, PerformanceCriteria } from "@/types";
|
import type {
|
||||||
|
CompetencePage,
|
||||||
|
CompetenceProfilePage,
|
||||||
|
CourseWagtailPage,
|
||||||
|
PerformanceCriteria,
|
||||||
|
} from "@/types";
|
||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
import { defineStore } from "pinia";
|
import { defineStore } from "pinia";
|
||||||
|
|
||||||
export type CompetenceStoreState = {
|
export type CompetenceStoreState = {
|
||||||
competenceProfilePage: CompetenceProfilePage | undefined;
|
competenceProfilePage: CompetenceProfilePage | undefined;
|
||||||
|
selectedCircle: { id: string; name: string };
|
||||||
|
availableCircles: { id: string; name: string }[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useCompetenceStore = defineStore({
|
export const useCompetenceStore = defineStore({
|
||||||
|
|
@ -13,10 +20,12 @@ export const useCompetenceStore = defineStore({
|
||||||
state: () => {
|
state: () => {
|
||||||
return {
|
return {
|
||||||
competenceProfilePage: undefined,
|
competenceProfilePage: undefined,
|
||||||
|
selectedCircle: { id: "all", name: "Circle: Alle" },
|
||||||
|
availableCircles: [],
|
||||||
} as CompetenceStoreState;
|
} as CompetenceStoreState;
|
||||||
},
|
},
|
||||||
getters: {
|
getters: {
|
||||||
flatPerformanceCriteria: (state, circleTitle = "") => {
|
flatPerformanceCriteria: (state) => {
|
||||||
if (!state.competenceProfilePage) {
|
if (!state.competenceProfilePage) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
@ -29,12 +38,40 @@ export const useCompetenceStore = defineStore({
|
||||||
["asc"]
|
["asc"]
|
||||||
);
|
);
|
||||||
|
|
||||||
if (circleTitle) {
|
if (state.selectedCircle.id !== "all") {
|
||||||
criteria = criteria.filter((c) => c.circle === circleTitle);
|
criteria = criteria.filter(
|
||||||
|
(c) => c.circle.translation_key === state.selectedCircle.id
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return criteria;
|
return criteria;
|
||||||
},
|
},
|
||||||
|
competences: (state) => {
|
||||||
|
if (state.competenceProfilePage?.children.length) {
|
||||||
|
return state.competenceProfilePage.children.filter((competence) => {
|
||||||
|
let criteria = competence.children;
|
||||||
|
if (state.selectedCircle.id != "all") {
|
||||||
|
criteria = criteria.filter((criteria) => {
|
||||||
|
return criteria.circle.translation_key === state.selectedCircle.id;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return criteria.length > 0;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return [];
|
||||||
|
},
|
||||||
|
criteriaByCompetence: (state) => {
|
||||||
|
return (competence: CompetencePage) => {
|
||||||
|
return competence.children.filter((criteria) => {
|
||||||
|
if (state.selectedCircle.id != "all") {
|
||||||
|
return criteria.circle.translation_key === state.selectedCircle.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
return competence.children;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
},
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
calcStatusCount(criteria: PerformanceCriteria[]) {
|
calcStatusCount(criteria: PerformanceCriteria[]) {
|
||||||
|
|
@ -65,6 +102,12 @@ export const useCompetenceStore = defineStore({
|
||||||
}
|
}
|
||||||
|
|
||||||
this.competenceProfilePage = competenceProfilePageData;
|
this.competenceProfilePage = competenceProfilePageData;
|
||||||
|
|
||||||
|
const circles = competenceProfilePageData.circles.map((c: CourseWagtailPage) => {
|
||||||
|
return { id: c.translation_key, name: `Circle: ${c.title}` };
|
||||||
|
});
|
||||||
|
this.availableCircles = [{ id: "all", name: "Circle: Alle" }, ...circles];
|
||||||
|
|
||||||
await this.parseCompletionData();
|
await this.parseCompletionData();
|
||||||
|
|
||||||
return this.competenceProfilePage;
|
return this.competenceProfilePage;
|
||||||
|
|
|
||||||
|
|
@ -125,6 +125,13 @@ export interface CourseWagtailPage {
|
||||||
completion_status_updated_at: string;
|
completion_status_updated_at: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface CircleLight {
|
||||||
|
readonly id: number;
|
||||||
|
readonly title: string;
|
||||||
|
readonly slug: string;
|
||||||
|
readonly translation_key: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface LearningContent extends CourseWagtailPage {
|
export interface LearningContent extends CourseWagtailPage {
|
||||||
type: "learnpath.LearningContent";
|
type: "learnpath.LearningContent";
|
||||||
minutes: number;
|
minutes: number;
|
||||||
|
|
@ -296,7 +303,7 @@ export interface MediaLibraryPage extends CourseWagtailPage {
|
||||||
export interface PerformanceCriteria extends CourseWagtailPage {
|
export interface PerformanceCriteria extends CourseWagtailPage {
|
||||||
type: "competence.PerformanceCriteria";
|
type: "competence.PerformanceCriteria";
|
||||||
competence_id: string;
|
competence_id: string;
|
||||||
circle: string;
|
circle: CircleLight;
|
||||||
course_category: CourseCategory;
|
course_category: CourseCategory;
|
||||||
learning_unit: CourseWagtailPage;
|
learning_unit: CourseWagtailPage;
|
||||||
}
|
}
|
||||||
|
|
@ -310,5 +317,6 @@ export interface CompetencePage extends CourseWagtailPage {
|
||||||
export interface CompetenceProfilePage extends CourseWagtailPage {
|
export interface CompetenceProfilePage extends CourseWagtailPage {
|
||||||
type: "competence.CompetenceProfilePage";
|
type: "competence.CompetenceProfilePage";
|
||||||
course: Course;
|
course: Course;
|
||||||
|
circles: CircleLight[];
|
||||||
children: CompetencePage[];
|
children: CompetencePage[];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue