Add mobile selection
This commit is contained in:
parent
9b8bbf5ebc
commit
7ce195f518
|
|
@ -5,6 +5,7 @@ import { computed } from "vue";
|
|||
interface DropdownSelectable {
|
||||
id: number | string;
|
||||
name: string;
|
||||
iconName?: string;
|
||||
}
|
||||
|
||||
// https://stackoverflow.com/questions/64775876/vue-3-pass-reactive-object-to-component-with-two-way-binding
|
||||
|
|
@ -40,8 +41,11 @@ const dropdownSelected = computed({
|
|||
<Listbox v-model="dropdownSelected" as="div">
|
||||
<div class="mt-1 relative w-full">
|
||||
<ListboxButton
|
||||
class="bg-white relative w-full border pl-5 pr-10 py-3 text-left cursor-default font-bold"
|
||||
class="bg-white relative w-full border pl-5 pr-10 py-3 text-left cursor-default font-bold flex flex-row items-center"
|
||||
>
|
||||
<span v-if="dropdownSelected.iconName" class="mr-4">
|
||||
<component :is="dropdownSelected.iconName"></component>
|
||||
</span>
|
||||
<span class="block truncate">{{ dropdownSelected.name }}</span>
|
||||
<span
|
||||
class="absolute inset-y-0 right-0 flex items-center pr-2 pointer-events-none"
|
||||
|
|
@ -70,7 +74,11 @@ const dropdownSelected = computed({
|
|||
active ? 'text-white bg-blue-900' : 'text-black',
|
||||
'cursor-default select-none relative py-2 pl-3 pr-9',
|
||||
]"
|
||||
class="flex flex-row items-center"
|
||||
>
|
||||
<span v-if="item.iconName" class="mr-4">
|
||||
<component :is="item.iconName"></component>
|
||||
</span>
|
||||
<span
|
||||
:class="[
|
||||
dropdownSelected ? 'font-semibold' : 'font-normal',
|
||||
|
|
|
|||
|
|
@ -2,10 +2,10 @@
|
|||
import CompetenceProgress from "@/components/competences/CompetenceProgress.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 * as log from "loglevel";
|
||||
import {computed} from "vue";
|
||||
import { computed } from "vue";
|
||||
|
||||
log.debug("CompetenceIndexPage created");
|
||||
|
||||
|
|
@ -133,7 +133,10 @@ const countStatus = computed(() => {
|
|||
<it-icon-arrow-right></it-icon-arrow-right>
|
||||
</router-link>
|
||||
</div>
|
||||
<div v-if="failedCriteria.length > 0" class="bg-white px-8 py-4 lg:py-8 l mb-4 lg:mb-8">
|
||||
<div
|
||||
v-if="failedCriteria.length > 0"
|
||||
class="bg-white px-8 py-4 lg:py-8 l mb-4 lg:mb-8"
|
||||
>
|
||||
<div class="border-b flex flex-row items-center pb-4 mb-4">
|
||||
<it-icon-smiley-thinking class="w-11 h-11 mr-5"></it-icon-smiley-thinking>
|
||||
<h3>«Das muss ich nochmals anschauen»</h3>
|
||||
|
|
|
|||
|
|
@ -9,15 +9,44 @@ import {computed, ref} from "vue";
|
|||
|
||||
log.debug("CompetencesMainView created");
|
||||
|
||||
const competenceStore = useCompetenceStore();
|
||||
interface MenuItem {
|
||||
id: CourseCompletionStatus;
|
||||
name: string;
|
||||
iconName: string;
|
||||
}
|
||||
|
||||
const activeState: Ref<CourseCompletionStatus> = ref("fail");
|
||||
const competenceStore = useCompetenceStore();
|
||||
|
||||
const shownCriteria = computed(() => {
|
||||
return competenceStore.flatPerformanceCriteria.filter((criteria) => {
|
||||
return criteria.completion_status === activeState.value;
|
||||
return criteria.completion_status === activeMenuItem.value.id;
|
||||
});
|
||||
});
|
||||
|
||||
const mobileMenuItems: MenuItem[] = [
|
||||
{
|
||||
id: "fail",
|
||||
name: "«Das muss ich nochmals anschauen»",
|
||||
iconName: "it-icon-smiley-thinking",
|
||||
},
|
||||
{
|
||||
id: "success",
|
||||
name: "«Ja, ich kann das»",
|
||||
iconName: "it-icon-smiley-happy",
|
||||
},
|
||||
{
|
||||
id: "unknown",
|
||||
name: "Nicht eingeschätzt",
|
||||
iconName: "it-icon-smiley-neutral",
|
||||
},
|
||||
];
|
||||
|
||||
const activeMenuItem: Ref<MenuItem> = ref(mobileMenuItems[0]);
|
||||
|
||||
function updateActiveState(status: CourseCompletionStatus) {
|
||||
activeMenuItem.value =
|
||||
mobileMenuItems.find((item) => status === item.id) || mobileMenuItems[0];
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
@ -38,32 +67,30 @@ const shownCriteria = computed(() => {
|
|||
class="w-full lg:w-96 mt-4 lg:mt-0"
|
||||
:items="competenceStore.availableCircles"
|
||||
></ItDropdownSelect>
|
||||
<div class="lg:hidden w-full">
|
||||
<ItDropdownSelect
|
||||
v-model="activeMenuItem"
|
||||
class="w-full lg:w-96 mt-4 lg:mt-0"
|
||||
:items="mobileMenuItems"
|
||||
></ItDropdownSelect>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-white p-8">
|
||||
<div class="border-b flex flex-col lg:flex-row lg:items-center pb-4 mb-4">
|
||||
<div
|
||||
class="border-b flex flex-col lg:flex-row lg:items-center pb-4 mb-4 hidden lg:block"
|
||||
>
|
||||
<button
|
||||
:class="{ 'bg-gray-200': activeState === 'fail' }"
|
||||
v-for="item in mobileMenuItems"
|
||||
:key="item.id"
|
||||
:class="{
|
||||
'bg-gray-200': activeMenuItem.id === item.id,
|
||||
'mr-6': item.id !== 'unknown',
|
||||
}"
|
||||
class="flex flex-row items-center py-4 px-2 mr-6"
|
||||
@click="activeState = 'fail'"
|
||||
@click="updateActiveState(item.id)"
|
||||
>
|
||||
<span class="inline-block mr-2">«Das muss ich nochmals anschauen»</span>
|
||||
<span><it-icon-smiley-thinking></it-icon-smiley-thinking></span>
|
||||
</button>
|
||||
<button
|
||||
:class="{ 'bg-gray-200': activeState === 'success' }"
|
||||
class="flex flex-row items-center py-4 px-2 mr-6"
|
||||
@click="activeState = 'success'"
|
||||
>
|
||||
<span class="inline-block mr-2">«Ja, ich kann das»</span>
|
||||
<span><it-icon-smiley-happy></it-icon-smiley-happy></span>
|
||||
</button>
|
||||
<button
|
||||
:class="{ 'bg-gray-200': activeState === 'unknown' }"
|
||||
class="flex flex-row items-center py-4 px-2"
|
||||
@click="activeState = 'unknown'"
|
||||
>
|
||||
<span class="inline-block mr-2">Nicht eingeschätzt</span>
|
||||
<span><it-icon-smiley-neutral></it-icon-smiley-neutral></span>
|
||||
<span class="inline-block mr-2">{{ item.name }}</span>
|
||||
<component :is="item.iconName"></component>
|
||||
</button>
|
||||
</div>
|
||||
<ul class="mb-6">
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ const createContinueUrl = (learningPath: LearningPath): [string, boolean] => {
|
|||
</button>
|
||||
</div>
|
||||
<LearningPathDiagram
|
||||
class="mx-auto max-w-[1920px] max-h-[380px] w-full"
|
||||
class="mx-auto max-w-[1920px] max-h-[380px] w-full px-4"
|
||||
identifier="mainVisualization"
|
||||
:vertical="false"
|
||||
></LearningPathDiagram>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<script setup lang="ts">
|
||||
import {useMediaLibraryStore} from "@/stores/mediaLibrary";
|
||||
import { useMediaLibraryStore } from "@/stores/mediaLibrary";
|
||||
import * as log from "loglevel";
|
||||
import {onMounted} from "vue";
|
||||
import { onMounted } from "vue";
|
||||
|
||||
log.debug("MediaLibraryView created");
|
||||
|
||||
|
|
@ -25,7 +25,10 @@ onMounted(async () => {
|
|||
<template>
|
||||
<div class="bg-gray-200">
|
||||
<nav class="px-6 py-4 border-b bg-white">
|
||||
<ul v-if="mediaLibraryStore.mediaLibraryPage" class="overflow-auto whitespace-nowrap scrollbar">
|
||||
<ul
|
||||
v-if="mediaLibraryStore.mediaLibraryPage"
|
||||
class="overflow-auto whitespace-nowrap scrollbar"
|
||||
>
|
||||
<li class="lg:ml-12 inline-block">
|
||||
<router-link :to="mediaLibraryStore.mediaLibraryPage.frontend_url">
|
||||
Übersicht
|
||||
|
|
|
|||
Loading…
Reference in New Issue