Merged in feature/instrument-overview (pull request #60)

Feature/instrument overview

Approved-by: Christian Cueni
This commit is contained in:
Ramon Wenger 2020-05-07 10:12:02 +00:00
commit 795e5a9ea0
13 changed files with 286 additions and 214 deletions

View File

@ -1,41 +0,0 @@
<template>
<router-link tag="div" :to="{name: 'instrument', params: {slug: slug}}" class="instrument-teaser">
<h3 class="instrument-teaser__title">{{title}}</h3>
<p class="instrument-teaser__text" v-html="teaser">
</p>
</router-link>
</template>
<script>
import teaser from '@/helpers/teaser';
export default {
props: ['title', 'contents', 'slug'],
computed: {
teaser() {
return teaser(this.contents);
}
}
}
</script>
<style scoped lang="scss">
@import "@/styles/_variables.scss";
@import "@/styles/_mixins.scss";
.instrument-teaser {
height: 250px;
box-sizing: border-box;
padding: $medium-spacing;
@include widget-shadow;
width: 100%;
cursor: pointer;
&__title {
@include heading-3;
margin-bottom: $small-spacing;
line-height: 1.2;
}
}
</style>

View File

@ -3,13 +3,14 @@
<sub-navigation-item title="Themen">
<book-topic-navigation></book-topic-navigation>
</sub-navigation-item>
<sub-navigation-item title="Instrument">
<instrument-navigation></instrument-navigation>
</sub-navigation-item>
<router-link :to="{name: 'instrument-overview'}" activeClass="sub-navigation-item--active" class="sub-navigation-item">
<span class="sub-navigation-item__title">Instrumente</span>
</router-link>
<!--<sub-navigation-item title="News">-->
<!--<template slot="title">-->
<!--<h2 class="sub-navigation__title" slot="title">ABU News</h2>-->
<!--</template>-->
<!--<template slot="title">-->
<!--<h2 class="sub-navigation__title" slot="title">ABU News</h2>-->
<!--</template>-->
<!--</sub-navigation-item>-->
</aside>
</template>
@ -17,13 +18,11 @@
<script>
import SubNavigationItem from '@/components/book-navigation/SubNavigationItem';
import BookTopicNavigation from '@/components/book-navigation/BookTopicNavigation';
import InstrumentNavigation from '@/components/book-navigation/InstrumentNavigation';
export default {
components: {
SubNavigationItem,
BookTopicNavigation,
InstrumentNavigation
BookTopicNavigation
}
}
</script>

View File

@ -0,0 +1,103 @@
<template>
<nav class="top-navigation" :class="{'top-navigation--mobile': mobile}">
<div class="top-navigation__item">
<router-link to="/book/topic/berufliche-grundbildung" active-class="top-navigation__link--active"
:class="{'top-navigation__link--active': isActive('book')}"
@click.native="hideMobileNavigation"
class="top-navigation__link">Inhalte
</router-link>
<mobile-subnavigation v-if="mobile"></mobile-subnavigation>
</div>
<div class="top-navigation__item">
<router-link to="/rooms" active-class="top-navigation__link--active" @click.native="hideMobileNavigation"
class="top-navigation__link">Räume
</router-link>
</div>
<div class="top-navigation__item">
<router-link to="/portfolio" active-class="top-navigation__link--active" @click.native="hideMobileNavigation"
class="top-navigation__link">Portfolio
</router-link>
</div>
</nav>
</template>
<script>
import MobileSubnavigation from '@/components/book-navigation/MobileSubnavigation';
export default {
props: {
mobile: {
default: false
}
},
components: {
MobileSubnavigation
},
methods: {
isActive(linkName) {
return linkName === 'book' && this.$route.path.indexOf('module') > -1;
},
hideMobileNavigation() {
this.$store.dispatch('showMobileNavigation', false);
}
}
}
</script>
<style scoped lang="scss">
@import "@/styles/_variables.scss";
@import "@/styles/_mixins.scss";
.top-navigation {
display: flex;
&__link {
padding: 0 24px;
@include default-link;
}
$parent: &;
&--mobile {
flex-direction: column;
#{$parent}__link {
color: $color-white;
@include heading-4;
line-height: 2.5em;
padding: 0;
display: block;
margin-bottom: 0.5*$small-spacing;
&:only-child {
margin-bottom: 0;
}
}
#{$parent}__item {
border-bottom: 1px solid $color-white;
&:nth-child(1) {
order: 3;
border-bottom: 0;
}
&:nth-child(2) {
order: 1;
}
&:nth-child(3) {
order: 2;
}
}
}
}
</style>

View File

@ -1,31 +0,0 @@
<template>
<div>
<router-link tag="div" class="book-subnavigation__item"
:class="{'book-subnavigation__item--mobile': mobile}"
@click.native="hideMobileNavigation"
to="/instruments/sprache-kommunikation">Sprache und
Kommunikation
</router-link>
<router-link tag="div" class="book-subnavigation__item"
:class="{'book-subnavigation__item--mobile': mobile}"
@click.native="hideMobileNavigation"
to="/instruments/gesellschaft">Gesellschaft
</router-link>
</div>
</template>
<script>
export default {
props: {
mobile: {
default: false
}
},
methods: {
hideMobileNavigation() {
this.$store.dispatch('showMobileNavigation', false);
}
}
}
</script>

View File

@ -6,8 +6,11 @@
</div>
<div class="mobile-subnavigation__section">
<h3 class="mobile-subnavigation__title">Instrumente</h3>
<instrument-navigation :mobile="true"></instrument-navigation>
<router-link :to="{name: 'instrument-overview'}" class="sub-navigation-item book-subnavigation">
<span class="sub-navigation-item__title book-subnavigation__item--mobile book-subnavigation__item">
Instrumente
</span>
</router-link>
</div>
</div>
@ -15,12 +18,10 @@
<script>
import BookTopicNavigation from '@/components/book-navigation/BookTopicNavigation';
import InstrumentNavigation from '@/components/book-navigation/InstrumentNavigation';
export default {
components: {
BookTopicNavigation,
InstrumentNavigation
BookTopicNavigation
},
}
</script>

View File

@ -3,9 +3,9 @@
<input type="checkbox"
class="base-input-container__input"
:checked="checked"
@click.prevent="$emit('input', $event.target.checked, item)"
v-on:input.prevent="$emit('input', $event.target.checked, item)">
<span class="base-input-container__icon"
@input.prevent="$emit('input', $event.target.checked, item)"
>
<span class="base-input-container__icon checkbox"
:class="{'base-input-container__checkbox': type==='checkbox', 'base-input-container__radiobutton': type === 'radiobutton'}">
<tick v-if="type === 'checkbox'"></tick>
<circle-icon v-if="type === 'radiobutton'"></circle-icon>

View File

@ -0,0 +1,97 @@
<template>
<div class="instrument-filter">
<checkbox
class="instrument-filter__checkbox"
v-for="(type, i) in types"
:checked="type.enabled"
:class="`instrument-filter__checkbox--${type.cls}`"
:label="type.label"
:key="i"
@input="change($event, i)"
/>
</div>
</template>
<script>
import Checkbox from '@/components/Checkbox';
export default {
data() {
return {
filter: [],
types: [
{
label: 'Sprache und Kommunikation',
enabled: true,
prop: 'LANGUAGE_COMMUNICATION',
cls: 'language'
},
{
label: 'Gesellschaft',
enabled: true,
prop: 'SOCIETY',
cls: 'society'
},
{
label: 'Überfachliches Instrument',
enabled: true,
prop: 'INTERDISCIPLINARY',
cls: 'interdisciplinary'
},
]
}
},
methods: {
change(enabled, index) {
let type = this.types[index];
this.types = [
...this.types.slice(0, index),
{
...type,
enabled
},
...this.types.slice(index + 1),
];
this.$emit('filter',
this.types
.filter(t => t.enabled)
.map(t => t.prop)
)
}
},
components: {
Checkbox
}
}
</script>
<style scoped lang="scss">
@import "@/styles/_variables.scss";
.instrument-filter {
display: flex;
align-content: center;
&__checkbox {
&--language {
/deep/ input:checked + .checkbox {
background-color: $color-accent-1-dark;
}
}
&--society {
/deep/ input:checked + .checkbox {
background-color: $color-accent-2-dark;
}
}
&--interdisciplinary {
/deep/ input:checked + .checkbox {
background-color: $color-accent-4-dark;
}
}
}
}
</style>

View File

@ -30,7 +30,6 @@
<script>
import ObjectiveGroups from '@/components/objective-groups/ObjectiveGroups.vue';
import ObjectiveGroupControl from '@/components/objective-groups/ObjectiveGroupControl.vue';
import Chapter from '@/components/Chapter.vue';
import UPDATE_OBJECTIVE_PROGRESS_MUTATION from '@/graphql/gql/mutations/updateObjectiveProgress.gql';
@ -47,7 +46,6 @@
components: {
BookmarkActions,
ObjectiveGroups,
ObjectiveGroupControl,
Chapter
},

View File

@ -1,73 +0,0 @@
<template>
<div class="objective-group objective-group-control">
<h4>{{group.displayTitle}}</h4>
<ul class="objective-group__objective-list objective-group__objective-list--no-list">
<li v-if="objectives" class="objective-group__objective" v-for="objective in objectives" :key="objective.id">
<checkbox :checked="objective.done"
:item="objective"
:label="objective.text"
@input="updateObjectiveProgress"
></checkbox>
</li>
</ul>
</div>
</template>
<script>
import Checkbox from '@/components/Checkbox';
export default {
name: 'objective-group-control',
components: {Checkbox},
props: {
group: {
required: true,
type: Object
}
},
methods: {
updateObjectiveProgress(checked, objective) {
this.$emit('updateObjectiveProgress', checked, objective.id);
},
objectiveIsDone(objective) {
return objective.objectiveProgress.length > 0 && objective.objectiveProgress[0].done
}
},
computed: {
objectives() {
return this.group.objectives.map(objective => {
return Object.assign({}, objective, { done: this.objectiveIsDone(objective) })
});
}
}
}
</script>
<style scoped lang="scss">
@import "@/styles/_variables.scss";
@import "@/styles/_functions.scss";
.objective-group__objective-list /deep/ {
.base-input-container {
position: relative;
&__checkbox {
background-color: white;
position: absolute;
top: 5px;
}
&__label {
font-family: $serif-font-family;
margin-left: 30px;
}
}
}
</style>

View File

@ -1,22 +1,11 @@
<template>
<div>
<template v-if="control">
<objective-group-control
v-for="(group, index) in objectiveGroups"
:key="`${group.id}${index}`"
:group="group"
@updateObjectiveProgress="updateObjectiveProgress"></objective-group-control>
</template>
<template v-if="!control">
<objective-group v-for="group in objectiveGroups" :key="group.id" :group="group"></objective-group>
</template>
<objective-group v-for="group in objectiveGroups" :key="group.id" :group="group"></objective-group>
</div>
</template>
<script>
import ObjectiveGroup from '@/components/objective-groups/ObjectiveGroup';
import ObjectiveGroupControl from '@/components/objective-groups/ObjectiveGroupControl';
import {meQuery} from '@/graphql/queries';
import {withoutOwnerFirst} from '@/helpers/sorting';
@ -30,8 +19,7 @@
},
components: {
ObjectiveGroup,
ObjectiveGroupControl
ObjectiveGroup
},
apollo: {

View File

@ -0,0 +1,13 @@
query InstrumentQuery {
instruments {
edges {
node {
id
title
contents
slug
type
}
}
}
}

View File

@ -2,54 +2,59 @@
<div class="instrument-overview">
<div class="instrument-overview__heading">
<h1 class="instrument-overview__title">
Instrument:<br> {{instrumentType}}
Instrumente
</h1>
</div>
<instrument-filter @filter="updateFilter" class="instrument-overview__filter">
</instrument-filter>
<div class="instrument-overview__list">
<instrument-teaser
v-bind="instrument"
v-for="instrument in instruments"
:key="instrument.id"
></instrument-teaser>
<router-link
class="instrument-overview__list-item"
tag="div"
:to="{name: 'instrument', params: {slug: instrument.slug}}"
v-for="instrument in filteredInstruments"
:key="instrument.id">
{{instrument.title}}
</router-link>
</div>
</div>
</template>
<script>
import InstrumentTeaser from '@/components/InstrumentTeaser';
import INSTRUMENTS_QUERY from '@/graphql/gql/instrumentsByTypeQuery.gql';
import InstrumentFilter from '@/components/instruments/InstrumentFilter';
import INSTRUMENTS_QUERY from '@/graphql/gql/instrumentsQuery.gql';
export default {
components: {
InstrumentTeaser
},
computed: {
instrumentType () {
return this.$route.params.slug === 'gesellschaft' ? 'Gesellschaft' : 'Sprache und Kommunikation';
}
InstrumentFilter
},
apollo: {
instruments: {
query: INSTRUMENTS_QUERY,
variables() {
return {
type: this.$route.params.slug === 'gesellschaft' ? 'society' : 'language_communication'
}
},
manual: true,
result({data, loading, networkStatus}) {
if (!loading) {
this.instruments = this.$getRidOfEdges(data).instruments;
}
update(data) {
return this.$getRidOfEdges(data).instruments;
}
}
},
computed: {
filteredInstruments() {
return this.instruments.filter(instrument => this.filter.includes(instrument.type) || !this.filter.length);
}
},
methods: {
updateFilter(filter) {
this.filter = filter
}
},
data() {
return {
instruments: []
instruments: [],
filter: []
}
}
}
@ -57,19 +62,21 @@
<style scoped lang="scss">
@import "@/styles/_variables.scss";
@import "@/styles/_mixins.scss";
.instrument-overview {
display: grid;
grid-template-rows: auto 1fr;
grid-template-rows: auto auto 1fr;
justify-items: center;
width: 100%;
justify-self: center;
width: 800px;
max-width: 100%;
&__heading {
padding: 2*$large-spacing 0;
background-color: $color-accent-2;
width: 100%;
display: flex;
justify-content: center;
justify-content: flex-start;
}
&__title {
@ -78,15 +85,26 @@
margin-bottom: 0;
}
&__filter {
justify-self: start;
}
&__list {
padding: $large-spacing 0;
max-width: 1200px;
width: 100%;
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: auto;
grid-column-gap: $large-spacing;
grid-row-gap: $large-spacing;
display: flex;
flex-direction: column;
}
&__list-item {
padding: $medium-spacing 0;
border-top: 1px solid $color-silver;
@include regular-text;
&:last-of-type {
border-bottom: 1px solid $color-silver;
}
}
}
</style>

View File

@ -84,7 +84,7 @@ const routes = [
},
{path: '/article/:slug', name: 'article', component: article, meta: {layout: 'simple'}},
{
path: '/instruments/:slug',
path: '/instruments/',
name: 'instrument-overview',
component: instrumentOverview,
meta: {subnavigation: true}