Refactor subnavigation and implement module subnavigation

This commit is contained in:
Ramon Wenger 2019-07-16 16:15:20 +02:00
parent d788466942
commit 98a8acac4f
13 changed files with 188 additions and 107 deletions

View File

@ -1,7 +1,9 @@
<template> <template>
<header class="header-bar"> <header class="header-bar">
<top-navigation></top-navigation> <top-navigation></top-navigation>
<router-link to="/" class="header-bar__logo" data-cy="home-link"><logo></logo></router-link> <router-link to="/" class="header-bar__logo" data-cy="home-link">
<logo></logo>
</router-link>
<div class="user-header"> <div class="user-header">
<router-link to="/me/activity"> <router-link to="/me/activity">
<user-widget v-bind="me"></user-widget> <user-widget v-bind="me"></user-widget>

View File

@ -1,48 +1,28 @@
<template> <template>
<aside class="book-navigation"> <aside class="sub-navigation">
<book-navigation-item title="Themen"> <sub-navigation-item title="Themen">
<book-topic-navigation></book-topic-navigation> <book-topic-navigation></book-topic-navigation>
</book-navigation-item> </sub-navigation-item>
<book-navigation-item title="Instrument"> <sub-navigation-item title="Instrument">
<div> <router-link tag="div" class="book-subnavigation__item" to="/basic-knowledge">Sprache und Kommunikation</router-link>
<router-link to="/basic-knowledge">Sprache und Kommunikation</router-link> <router-link tag="div" class="book-subnavigation__item" to="/basic-knowledge">Gesellschaft</router-link>
</div> </sub-navigation-item>
<div> <sub-navigation-item title="News">
<router-link to="/basic-knowledge">Gesellschaft</router-link>
</div>
</book-navigation-item>
<book-navigation-item title="News">
<template slot="title"> <template slot="title">
<h2 class="book-navigation__title" slot="title">ABU News</h2> <h2 class="sub-navigation__title" slot="title">ABU News</h2>
</template> </template>
</book-navigation-item> </sub-navigation-item>
</aside> </aside>
</template> </template>
<script> <script>
import BookNavigationItem from '@/components/book-navigation/BookNavigationItem'; import SubNavigationItem from '@/components/book-navigation/SubNavigationItem';
import BookTopicNavigation from '@/components/book-navigation/BookTopicNavigation'; import BookTopicNavigation from '@/components/book-navigation/BookTopicNavigation';
export default { export default {
components: { components: {
BookNavigationItem, SubNavigationItem,
BookTopicNavigation BookTopicNavigation
} }
} }
</script> </script>
<style scoped lang="scss">
@import "@/styles/_functions.scss";
@import "@/styles/_variables.scss";
@import "@/styles/_mixins.scss";
.book-navigation {
display: none;
@include desktop {
display: flex;
}
padding: $medium-spacing;
}
</style>

View File

@ -1,24 +1,44 @@
<template> <template>
<nav class="book-topics"> <nav class="book-topics">
<div class="book-topics__topic" <router-link :to="{name: 'topic', params: {topicSlug: topic.slug}}"
tag="div"
class="book-topics__topic book-subnavigation__item"
:class="{'book-topics__topic--active': topic.active}" :class="{'book-topics__topic--active': topic.active}"
v-for="topic in topics" v-for="topic in topics"
:key="topic.id">{{topic.id}}. {{topic.title}} :key="topic.id">
</div> {{topic.order}}.
{{topic.title}}
</router-link>
</nav> </nav>
</template> </template>
<script> <script>
import ALL_TOPICS_QUERY from '@/graphql/gql/allTopicsQuery.gql';
export default { export default {
data() { data() {
return { return {
topics: [ topics: [
{id: 2, title: 'Geld und Kauf', active: true},
{id: 3, title: 'Geld und Kauf', active: false},
{id: 4, title: 'Geld und Kauf', active: false},
{id: 5, title: 'Geld und Kauf', active: false},
] ]
} }
},
methods: {
topicId(id) {
return atob(id)
}
},
apollo: {
topics: {
query: ALL_TOPICS_QUERY,
manual: true,
result({data, loading, networkStatus}) {
if (!loading) {
this.topics = this.$getRidOfEdges(data).topics
}
}
}
} }
} }
</script> </script>
@ -27,18 +47,7 @@
@import "@/styles/_variables.scss"; @import "@/styles/_variables.scss";
.book-topics { .book-topics {
padding-left: 24px;
margin-bottom: 25px;
&__topic { &__topic {
font-family: $sans-serif-font-family;
font-size: toRem(14px);
margin-bottom: 20px;
color: $color-silver-dark;
&--active {
color: $color-brand;
}
} }
} }
</style> </style>

View File

@ -1,5 +1,5 @@
<template> <template>
<div class="sub-navigation-item" :class="{ 'sub-navigation-item--active': show}"> <div class="sub-navigation-item" :class="{ 'sub-navigation-item--active': show}" v-click-outside="close">
<div class="sub-navigation-item__title" @click="show = !show"> <div class="sub-navigation-item__title" @click="show = !show">
{{title}} {{title}}
<chevron-down class="sub-navigation-item__icon sub-navigation-item__chevron-down"></chevron-down> <chevron-down class="sub-navigation-item__icon sub-navigation-item__chevron-down"></chevron-down>
@ -27,6 +27,12 @@
return { return {
show: false show: false
} }
},
methods: {
close() {
this.show = false;
}
} }
} }
</script> </script>

View File

@ -1,12 +1,5 @@
<template> <template>
<div class="module"> <div class="module">
<toggle-solutions-for-module
:module="module.id"
:enabled="module.solutionsEnabled"
class="module__solution-toggle"
data-cy="toggle-enable-solutions"></toggle-solutions-for-module>
<h2 class="module__meta-title" id="meta-title">{{module.metaTitle}}</h2> <h2 class="module__meta-title" id="meta-title">{{module.metaTitle}}</h2>
<h1 class="module__title" data-cy="module-title">{{module.title}}</h1> <h1 class="module__title" data-cy="module-title">{{module.title}}</h1>
<img <img
@ -33,7 +26,6 @@
import ObjectiveGroupControl from '@/components/objective-groups/ObjectiveGroupControl.vue'; import ObjectiveGroupControl from '@/components/objective-groups/ObjectiveGroupControl.vue';
import AddObjectiveGroupButton from '@/components/AddObjectiveGroupButton'; import AddObjectiveGroupButton from '@/components/AddObjectiveGroupButton';
import Chapter from '@/components/Chapter.vue'; import Chapter from '@/components/Chapter.vue';
import ToggleSolutionsForModule from '@/components/ToggleSolutionsForModule.vue';
import UPDATE_OBJECTIVE_PROGRESS_MUTATION from '@/graphql/gql/mutations/updateObjectiveProgress.gql'; import UPDATE_OBJECTIVE_PROGRESS_MUTATION from '@/graphql/gql/mutations/updateObjectiveProgress.gql';
import UPDATE_LAST_MODULE_MUTATION from '@/graphql/gql/mutations/updateLastModule.gql'; import UPDATE_LAST_MODULE_MUTATION from '@/graphql/gql/mutations/updateLastModule.gql';
@ -47,8 +39,7 @@
ObjectiveGroups, ObjectiveGroups,
ObjectiveGroupControl, ObjectiveGroupControl,
AddObjectiveGroupButton, AddObjectiveGroupButton,
Chapter, Chapter
ToggleSolutionsForModule
}, },
props: { props: {
@ -155,10 +146,6 @@
-moz-box-sizing: border-box; -moz-box-sizing: border-box;
box-sizing: border-box; box-sizing: border-box;
&__solution-toggle {
margin-bottom: $large-spacing;
}
&__hero { &__hero {
margin-bottom: 35px; margin-bottom: 35px;
border-radius: 12px; border-radius: 12px;

View File

@ -1,49 +1,53 @@
<template> <template>
<div> <nav class="module-navigation sub-navigation">
<nav v-if="false" class="module-navigation"> <div class="sub-navigation-item">
<div class="module-navigation__module-content"> <router-link class="sub-navigation-item__title" :to="moduleContentLink">Modul</router-link>
<router-link </div>
tag="h3" <sub-navigation-item title="Ergebnisse">
:to="moduleContentLink" <router-link
class="module-navigation__heading" :to="submissionsLink(assignment)"
>Inhalte: {{module.metaTitle}} v-for="assignment in assignments"
</router-link> :key="assignment.id"
<div class="module-navigation__anchors" v-if="onModulePage"> class="module-navigation__anchor"
<a href="#" v-scroll-to="'#meta-title'" class="module-navigation__anchor">Einleitung</a> exact-active-class="module-navigation__anchor--active"
<a href="#" v-scroll-to="'#objectives'" class="module-navigation__anchor">Lernziele</a> >{{assignmentTitle(assignment)}}
</router-link>
</sub-navigation-item>
<div class="module-navigation__module-content" v-if="false">
<router-link
tag="h3"
:to="moduleContentLink"
class="module-navigation__heading"
>Inhalte: {{module.metaTitle}}
</router-link>
<div class="module-navigation__anchors" v-if="onModulePage">
<a href="#" v-scroll-to="'#meta-title'" class="module-navigation__anchor">Einleitung</a>
<a href="#" v-scroll-to="'#objectives'" class="module-navigation__anchor">Lernziele</a>
<a href="#" class="module-navigation__anchor" <a href="#" class="module-navigation__anchor"
v-scroll-to="chapterId(index)" v-scroll-to="chapterId(index)"
v-for="(chapter, index) in module.chapters" v-for="(chapter, index) in module.chapters"
:key="chapter.id">{{chapter.title}}</a> :key="chapter.id">{{chapter.title}}</a>
<a href="#" v-scroll-to="'#objectives-confirm'" class="module-navigation__anchor">Lernzielkontrolle</a> <a href="#" v-scroll-to="'#objectives-confirm'" class="module-navigation__anchor">Lernzielkontrolle</a>
</div>
</div> </div>
</div>
<div class="module-navigation__module-submissions" v-if="showResults"> <toggle-solutions-for-module
<router-link tag="h3" to="/module/submissions" class="module-navigation__heading">Ergebnisse: v-if="onModulePage && module.id"
{{module.metaTitle}} :module="module.id"
</router-link> :enabled="module.solutionsEnabled"
<div class="module-navigation__anchors"> class="module-navigation__solution-toggle"
<router-link data-cy="toggle-enable-solutions"></toggle-solutions-for-module>
:to="submissionsLink(assignment)" </nav>
v-for="assignment in assignments"
:key="assignment.id"
class="module-navigation__anchor"
exact-active-class="module-navigation__anchor--active"
>{{assignmentTitle(assignment)}}
</router-link>
</div>
</div>
</nav>
</div>
</template> </template>
<script> <script>
import {moduleQuery} from '@/graphql/queries'; import {moduleQuery} from '@/graphql/queries';
import ME_QUERY from '@/graphql/gql/meQuery.gql'; import ME_QUERY from '@/graphql/gql/meQuery.gql';
// import ASSIGNMENTS_QUERY from '@/graphql/gql/assignmentsQuery.gql';
import SubNavigationItem from '@/components/book-navigation/SubNavigationItem';
import ToggleSolutionsForModule from '@/components/ToggleSolutionsForModule';
export default { export default {
apollo: { apollo: {
@ -53,6 +57,11 @@
} }
}, },
components: {
SubNavigationItem,
ToggleSolutionsForModule
},
computed: { computed: {
onModulePage() { onModulePage() {
return this.$route.name === 'module'; return this.$route.name === 'module';
@ -110,9 +119,11 @@
position: sticky; position: sticky;
top: 75px; top: 75px;
display: none; display: none;
width: 100%;
box-sizing: border-box;
@include desktop { @include desktop {
display: block; display: flex;
} }
&__module-content { &__module-content {
@ -140,5 +151,9 @@
color: $color-brand; color: $color-brand;
} }
} }
&__solution-toggle {
margin-left: auto;
}
} }
</style> </style>

View File

@ -0,0 +1,12 @@
query TopicsQuery {
topics {
edges {
node {
id
order
title
slug
}
}
}
}

View File

@ -1,7 +1,7 @@
<template> <template>
<div class="book"> <div class="book">
<main class="book__content"> <main class="book__content">
<router-view></router-view> <router-view :key="$route.fullPath"></router-view>
</main> </main>
</div> </div>

View File

@ -74,7 +74,7 @@ const routes = [
subnavigation: true subnavigation: true
}, },
children: [ children: [
{path: 'topic/:topicSlug', component: topic, meta: {subnavigation: true}} {path: 'topic/:topicSlug', name: 'topic', component: topic, meta: {subnavigation: true}}
] ]
}, },
{ {

View File

@ -13,3 +13,67 @@
} }
} }
} }
.sub-navigation {
display: none;
@include desktop {
display: flex;
}
padding: $medium-spacing;
}
.sub-navigation-item {
z-index: 10;
margin-right: $large-spacing;
&__title {
@include small-text;
display: grid;
grid-template-columns: 1fr auto;
grid-column-gap: $small-spacing;
align-items: center;
cursor: pointer;
}
&__icon {
width: 12px;
height: 12px;
}
&__chevron-up {
display: none;
}
&__nav-items {
box-shadow: 0 4px 7px 0 rgba(0, 0, 0, 0.12);
position: absolute;
left: 0;
background-color: $color-white;
padding: $large-spacing;
width: 100%;
box-sizing: border-box;
&:empty {
display: none;
}
}
&--active &__title {
color: $color-brand;
}
&--active &__icon {
fill: $color-brand;
}
&--active &__chevron-up {
display: block;
}
&--active &__chevron-down {
display: none;
}
}

View File

@ -13,5 +13,5 @@
@import "objective-group"; @import "objective-group";
@import "article"; @import "article";
@import "actions"; @import "actions";
@import "top-navigation"; @import "navigation";
@import "survey"; @import "survey";

View File

@ -123,7 +123,7 @@ class TopicNode(DjangoObjectType):
class Meta: class Meta:
model = Topic model = Topic
only_fields = [ only_fields = [
'slug', 'title', 'meta_title', 'teaser', 'description', 'vimeo_id' 'slug', 'title', 'meta_title', 'teaser', 'description', 'vimeo_id', 'order'
] ]
filter_fields = { filter_fields = {
'slug': ['exact', 'icontains', 'in'], 'slug': ['exact', 'icontains', 'in'],

View File

@ -677,6 +677,12 @@ data = [
'title': 'Geld und Kauf', 'title': 'Geld und Kauf',
'teaser': 'Die berufliche Grundbildung lehrt Sie, den Arbeitsalltag erfolgreich zu bewältigen, Ihre Fähigkeiten zu entwickeln und beruflich flexibel zu sein. Ebenso wichtig ist der Umgang mit verschiedensten Mitmenschen. Eine angemessene mündliche Kommunikation erleichtert das Zusammenleben und Zusammenarbeiten.', 'teaser': 'Die berufliche Grundbildung lehrt Sie, den Arbeitsalltag erfolgreich zu bewältigen, Ihre Fähigkeiten zu entwickeln und beruflich flexibel zu sein. Ebenso wichtig ist der Umgang mit verschiedensten Mitmenschen. Eine angemessene mündliche Kommunikation erleichtert das Zusammenleben und Zusammenarbeiten.',
'modules': modules 'modules': modules
},
{
'order': 2,
'title': 'Berufliche Grundbildung',
'teaser': 'Yada yada bla bla',
'modules': ''
} }
] ]
}] }]