Create ModuleFilters dynamically
This commit is contained in:
parent
b5705cc991
commit
aa095ac7ea
|
|
@ -2,7 +2,7 @@
|
||||||
<div>
|
<div>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="radio-group">
|
<div class="radio-group">
|
||||||
<div v-for="(category, index) in firstLevelCategories" :key="index" class="radio-item">
|
<div class="radio-item" v-for="(category, index) in firstLevelCategories" :key="index" >
|
||||||
<input
|
<input
|
||||||
type="radio"
|
type="radio"
|
||||||
:value="category"
|
:value="category"
|
||||||
|
|
@ -10,13 +10,14 @@
|
||||||
v-model="selectedCategory"
|
v-model="selectedCategory"
|
||||||
@change="filterModules"
|
@change="filterModules"
|
||||||
/>
|
/>
|
||||||
<label :for="'category-' + index">{{ category }}</label>
|
<label :for="'category-' + index">{{ category.name }}</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="dropdown-container">
|
<div class="dropdown-container">
|
||||||
<select id="lernfeld-select" v-model="selectedLernfeld" @change="filterModules">
|
<select id="lernfeld-select" v-model="selectedLernfeld" @change="filterModules">
|
||||||
<option v-for="(lernfeld, index) in lernfeldOptions" :value="lernfeld" :key="index">
|
<option :value="lernfeld" v-for="(lernfeld, index) in lernfeldOptions" :key="index">
|
||||||
{{ lernfeld }}
|
{{ lernfeld.name }}
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -36,28 +37,63 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {computed, ref} from "vue";
|
import {computed, ref} from "vue";
|
||||||
import ModuleTeaser from "@/components/modules/ModuleTeaser.vue";
|
import ModuleTeaser from "@/components/modules/ModuleTeaser.vue";
|
||||||
|
import gql from "graphql-tag";
|
||||||
|
import {useQuery} from "@vue/apollo-composable";
|
||||||
|
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
modules: [];
|
modules: [];
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const selectedCategory = ref(null);
|
|
||||||
console.log("modules", props.modules)
|
|
||||||
|
|
||||||
|
const {result: moduleCategoriesResult} = useQuery(gql`
|
||||||
|
query ModuleCategoriesQuery {
|
||||||
|
moduleCategories {
|
||||||
|
name
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`);
|
||||||
|
|
||||||
const lernfeldOptions = ['Alle Lernfelder', 'Lernfeld 1', 'Lernfeld 2', 'Lernfeld 3', 'Lernfeld 4', 'Lernfeld 5'];
|
const nullCategory = {
|
||||||
const selectedLernfeld = ref('Alle Lernfelder');
|
name: '---',
|
||||||
|
id: null,
|
||||||
|
};
|
||||||
|
|
||||||
|
const selectedCategory = ref(nullCategory);
|
||||||
|
|
||||||
|
|
||||||
const firstLevelCategories = computed(() => {
|
const firstLevelCategories = computed(() => {
|
||||||
return ["Alle Lehrjahre", "1. Lehrjahr", "2. Lehrjahr", "3. Lehrjahr",];
|
return [nullCategory, ...moduleCategoriesResult.value?.moduleCategories || []];
|
||||||
});
|
});
|
||||||
|
const {result: moduleCategoryTypesResult} = useQuery(gql`
|
||||||
|
query ModuleCategoryTypesQuery {
|
||||||
|
moduleCategoryTypes {
|
||||||
|
name
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`);
|
||||||
|
|
||||||
|
const nullLernfeld = {
|
||||||
|
name: '---',
|
||||||
|
id: null,
|
||||||
|
};
|
||||||
|
|
||||||
|
const selectedLernfeld = ref(nullLernfeld);
|
||||||
|
|
||||||
|
|
||||||
|
const lernfeldOptions = computed(() => {
|
||||||
|
return [nullLernfeld, ...moduleCategoryTypesResult.value?.moduleCategoryTypes || []];
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
let filteredModules = computed(() => {
|
let filteredModules = computed(() => {
|
||||||
return filterModules();
|
return filterModules();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// "$flavor.textInstrumentFilterShowAll"
|
||||||
|
|
||||||
|
|
||||||
function filterModules() {
|
function filterModules() {
|
||||||
let filteredModules = props.modules;
|
let filteredModules = props.modules;
|
||||||
|
|
@ -66,16 +102,16 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// filter by Lehrjahr
|
// filter by Lehrjahr
|
||||||
if (selectedCategory.value !== 'Alle Lehrjahre') {
|
if (selectedCategory.value.name !== '---') {
|
||||||
filteredModules = filteredModules.filter((module) => {
|
filteredModules = filteredModules.filter((module) => {
|
||||||
return module.categoryName.includes(selectedCategory.value);
|
return module.categoryName.includes(selectedCategory.value.name);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
//filter by Lernfeld
|
//filter by Lernfeld
|
||||||
if (selectedLernfeld.value !== 'Alle Lernfelder') {
|
if (selectedLernfeld.value.name !== '---') {
|
||||||
filteredModules = filteredModules.filter((module) => {
|
filteredModules = filteredModules.filter((module) => {
|
||||||
return module.categoryTypeName.includes(selectedLernfeld.value);
|
return module.categoryTypeName.includes(selectedLernfeld.value.name);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,8 +42,8 @@ class Module(StrictHierarchyPage):
|
||||||
verbose_name_plural = "Module"
|
verbose_name_plural = "Module"
|
||||||
|
|
||||||
meta_title = models.CharField(max_length=255, help_text="e.g. 'Intro' or 'Modul 1'")
|
meta_title = models.CharField(max_length=255, help_text="e.g. 'Intro' or 'Modul 1'")
|
||||||
category = models.ForeignKey(ModuleCategory, on_delete=models.SET_NULL, null=True)
|
category = models.ForeignKey(ModuleCategory, on_delete=models.SET_NULL, blank=True, null=True)
|
||||||
category_type = models.ForeignKey(ModuleType, on_delete=models.SET_NULL, null=True)
|
category_type = models.ForeignKey(ModuleType, on_delete=models.SET_NULL, blank=True, null=True)
|
||||||
|
|
||||||
|
|
||||||
hero_image = models.ForeignKey(
|
hero_image = models.ForeignKey(
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,8 @@ class ModuleNode(DjangoObjectType):
|
||||||
"hero_image",
|
"hero_image",
|
||||||
"hero_source",
|
"hero_source",
|
||||||
"topic",
|
"topic",
|
||||||
|
"category_name",
|
||||||
|
"category_type_name",
|
||||||
]
|
]
|
||||||
filter_fields = {
|
filter_fields = {
|
||||||
"slug": ["exact", "icontains", "in"],
|
"slug": ["exact", "icontains", "in"],
|
||||||
|
|
@ -52,6 +54,8 @@ class ModuleNode(DjangoObjectType):
|
||||||
snapshots = graphene.List("books.schema.nodes.SnapshotNode")
|
snapshots = graphene.List("books.schema.nodes.SnapshotNode")
|
||||||
objective_groups = graphene.List(ObjectiveGroupNode)
|
objective_groups = graphene.List(ObjectiveGroupNode)
|
||||||
assignments = graphene.List(AssignmentNode)
|
assignments = graphene.List(AssignmentNode)
|
||||||
|
category_name = graphene.String()
|
||||||
|
category_type_name = graphene.String()
|
||||||
|
|
||||||
def resolve_chapters(self, info, **kwargs):
|
def resolve_chapters(self, info, **kwargs):
|
||||||
return Chapter.get_by_parent(self)
|
return Chapter.get_by_parent(self)
|
||||||
|
|
@ -115,7 +119,6 @@ class ModuleNode(DjangoObjectType):
|
||||||
def resolve_assignments(parent: Module, info, **kwargs):
|
def resolve_assignments(parent: Module, info, **kwargs):
|
||||||
return parent.assignments.all()
|
return parent.assignments.all()
|
||||||
|
|
||||||
|
|
||||||
class RecentModuleNode(DjangoObjectType):
|
class RecentModuleNode(DjangoObjectType):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = RecentModule
|
model = RecentModule
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
from graphene import relay
|
||||||
|
from graphene import relay
|
||||||
|
from graphene_django import DjangoObjectType
|
||||||
|
|
||||||
|
from books.models import ModuleType
|
||||||
|
|
||||||
|
|
||||||
|
class ModuleCategoryTypeNode(DjangoObjectType):
|
||||||
|
class Meta:
|
||||||
|
model = ModuleType
|
||||||
|
interfaces = (relay.Node,)
|
||||||
|
only_fields = [
|
||||||
|
"id",
|
||||||
|
"name",
|
||||||
|
]
|
||||||
|
|
@ -7,7 +7,9 @@ from core.logger import get_logger
|
||||||
from .connections import TopicConnection, ModuleConnection
|
from .connections import TopicConnection, ModuleConnection
|
||||||
from .nodes import ContentBlockNode, ChapterNode, ModuleNode, NotFoundFailure, SnapshotNode, \
|
from .nodes import ContentBlockNode, ChapterNode, ModuleNode, NotFoundFailure, SnapshotNode, \
|
||||||
TopicOr404Node
|
TopicOr404Node
|
||||||
from ..models import Book, Topic, Module, Chapter, Snapshot
|
from .nodes.module_category import ModuleCategoryNode
|
||||||
|
from .nodes.module_category_type import ModuleCategoryTypeNode
|
||||||
|
from ..models import Book, Topic, Module, Chapter, Snapshot, ModuleCategory, ModuleType
|
||||||
|
|
||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|
@ -25,6 +27,12 @@ class BookQuery(object):
|
||||||
modules = relay.ConnectionField(ModuleConnection)
|
modules = relay.ConnectionField(ModuleConnection)
|
||||||
chapters = DjangoFilterConnectionField(ChapterNode)
|
chapters = DjangoFilterConnectionField(ChapterNode)
|
||||||
|
|
||||||
|
module_category = graphene.Field(ModuleCategoryNode, id=graphene.ID(required=True))
|
||||||
|
module_categories = graphene.List(ModuleCategoryNode)
|
||||||
|
|
||||||
|
module_category_type= graphene.Field(ModuleCategoryTypeNode, id=graphene.ID(required=True))
|
||||||
|
module_category_types = graphene.List(ModuleCategoryTypeNode)
|
||||||
|
|
||||||
def resolve_books(self, *args, **kwargs):
|
def resolve_books(self, *args, **kwargs):
|
||||||
return Book.objects.filter(**kwargs).live()
|
return Book.objects.filter(**kwargs).live()
|
||||||
|
|
||||||
|
|
@ -70,3 +78,43 @@ class BookQuery(object):
|
||||||
except Topic.DoesNotExist:
|
except Topic.DoesNotExist:
|
||||||
return NotFoundFailure
|
return NotFoundFailure
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def resolve_module_category(self, info, **kwargs):
|
||||||
|
id = kwargs.get('id')
|
||||||
|
try:
|
||||||
|
if id is not None:
|
||||||
|
module_category = get_object(Module, id)
|
||||||
|
return module_category
|
||||||
|
|
||||||
|
except Module.DoesNotExist:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def resolve_module_categories(self, *args, **kwargs):
|
||||||
|
return ModuleCategory.objects.filter(**kwargs)
|
||||||
|
|
||||||
|
def resolve_module_category_type(self, info, **kwargs):
|
||||||
|
id = kwargs.get('id')
|
||||||
|
try:
|
||||||
|
if id is not None:
|
||||||
|
module_category_type = get_object(Module, id)
|
||||||
|
return module_category_type
|
||||||
|
|
||||||
|
except Module.DoesNotExist:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def resolve_module_category_types(self, *args, **kwargs):
|
||||||
|
return ModuleType.objects.filter(**kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class ModuleTypeQuery(graphene.ObjectType):
|
||||||
|
node = relay.Node.Field()
|
||||||
|
name = graphene.String()
|
||||||
|
id = graphene.ID()
|
||||||
|
|
|
||||||
|
|
@ -236,7 +236,7 @@ interface ChapterInterface {
|
||||||
title: String
|
title: String
|
||||||
}
|
}
|
||||||
|
|
||||||
type ChapterNode implements Node & ChapterInterface {
|
type ChapterNode implements Node, ChapterInterface {
|
||||||
title: String
|
title: String
|
||||||
slug: String!
|
slug: String!
|
||||||
description: String
|
description: String
|
||||||
|
|
@ -306,7 +306,7 @@ interface ContentBlockInterface {
|
||||||
type: String
|
type: String
|
||||||
}
|
}
|
||||||
|
|
||||||
type ContentBlockNode implements Node & ContentBlockInterface {
|
type ContentBlockNode implements Node, ContentBlockInterface {
|
||||||
title: String
|
title: String
|
||||||
slug: String!
|
slug: String!
|
||||||
hiddenFor: [SchoolClassNode]
|
hiddenFor: [SchoolClassNode]
|
||||||
|
|
@ -621,6 +621,11 @@ type ModuleBookmarkNode {
|
||||||
module: ModuleNode!
|
module: ModuleNode!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ModuleCategoryNode implements Node {
|
||||||
|
id: ID!
|
||||||
|
name: String!
|
||||||
|
}
|
||||||
|
|
||||||
type ModuleConnection {
|
type ModuleConnection {
|
||||||
pageInfo: PageInfo!
|
pageInfo: PageInfo!
|
||||||
edges: [ModuleEdge]!
|
edges: [ModuleEdge]!
|
||||||
|
|
@ -660,6 +665,8 @@ type ModuleNode implements ModuleInterface {
|
||||||
myContentBookmarks(offset: Int, before: String, after: String, first: Int, last: Int): ContentBlockBookmarkNodeConnection
|
myContentBookmarks(offset: Int, before: String, after: String, first: Int, last: Int): ContentBlockBookmarkNodeConnection
|
||||||
myChapterBookmarks(offset: Int, before: String, after: String, first: Int, last: Int): ChapterBookmarkNodeConnection
|
myChapterBookmarks(offset: Int, before: String, after: String, first: Int, last: Int): ChapterBookmarkNodeConnection
|
||||||
snapshots: [SnapshotNode]
|
snapshots: [SnapshotNode]
|
||||||
|
categoryName: String
|
||||||
|
categoryTypeName: String
|
||||||
}
|
}
|
||||||
|
|
||||||
type ModuleNodeConnection {
|
type ModuleNodeConnection {
|
||||||
|
|
@ -928,6 +935,8 @@ type Query {
|
||||||
topics(before: String, after: String, first: Int, last: Int): TopicConnection
|
topics(before: String, after: String, first: Int, last: Int): TopicConnection
|
||||||
modules(before: String, after: String, first: Int, last: Int): ModuleConnection
|
modules(before: String, after: String, first: Int, last: Int): ModuleConnection
|
||||||
chapters(offset: Int, before: String, after: String, first: Int, last: Int, slug: String, title: String): ChapterNodeConnection
|
chapters(offset: Int, before: String, after: String, first: Int, last: Int, slug: String, title: String): ChapterNodeConnection
|
||||||
|
moduleCategory(id: ID!): ModuleCategoryNode
|
||||||
|
moduleCategories: [ModuleCategoryNode]
|
||||||
objectiveGroup(id: ID!): ObjectiveGroupNode
|
objectiveGroup(id: ID!): ObjectiveGroupNode
|
||||||
objectiveGroups(offset: Int, before: String, after: String, first: Int, last: Int, title: String, module_Slug: String): ObjectiveGroupNodeConnection
|
objectiveGroups(offset: Int, before: String, after: String, first: Int, last: Int, title: String, module_Slug: String): ObjectiveGroupNodeConnection
|
||||||
roomEntry(id: ID, slug: String): RoomEntryNode
|
roomEntry(id: ID, slug: String): RoomEntryNode
|
||||||
|
|
@ -1013,7 +1022,7 @@ type SnapshotChangesNode {
|
||||||
newContentBlocks: Int!
|
newContentBlocks: Int!
|
||||||
}
|
}
|
||||||
|
|
||||||
type SnapshotChapterNode implements Node & ChapterInterface {
|
type SnapshotChapterNode implements Node, ChapterInterface {
|
||||||
id: ID!
|
id: ID!
|
||||||
description: String
|
description: String
|
||||||
title: String
|
title: String
|
||||||
|
|
@ -1022,7 +1031,7 @@ type SnapshotChapterNode implements Node & ChapterInterface {
|
||||||
titleHidden: Boolean
|
titleHidden: Boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
type SnapshotContentBlockNode implements Node & ContentBlockInterface {
|
type SnapshotContentBlockNode implements Node, ContentBlockInterface {
|
||||||
id: ID!
|
id: ID!
|
||||||
title: String
|
title: String
|
||||||
contents: GenericStreamFieldType
|
contents: GenericStreamFieldType
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue