Refactor sidebar state to allow for multiple sidebars

This commit is contained in:
Ramon Wenger 2020-06-02 09:37:12 +02:00
parent 6d43226ebb
commit 5db13e9124
13 changed files with 73 additions and 38 deletions

View File

@ -10,7 +10,7 @@
<div class="user-header">
<a
class="user-header__sidebar-link"
@click="openSidebar()">
@click="openSidebar('profile')">
<current-class class="user-header__current-class"/>
</a>

View File

@ -5,7 +5,7 @@
<div
class="user-widget__avatar"
data-cy="user-widget-avatar"
@click="openSidebar()">
@click="openSidebar('profile')">
<avatar
:avatar-url="avatarUrl"
:icon-highlighted="isProfile"/>

View File

@ -7,7 +7,7 @@
tag="div"
class="book-topics__topic book-subnavigation__item"
v-for="topic in topics"
@click.native="hideMobileNavigation">
@click.native="closeSidebar('navigation')">
{{ topic.order }}.
{{ topic.title }}
</router-link>
@ -16,6 +16,7 @@
<script>
import ALL_TOPICS_QUERY from '@/graphql/gql/allTopicsQuery.gql';
import sidebarMixin from '@/mixins/sidebar';
export default {
props: {
@ -24,6 +25,8 @@
}
},
mixins: [sidebarMixin],
data() {
return {
topics: []
@ -33,9 +36,6 @@
methods: {
topicId(id) {
return atob(id)
},
hideMobileNavigation() {
this.$store.dispatch('showMobileNavigation', false);
}
},

View File

@ -1,12 +1,14 @@
<template>
<div class="mobile-navigation">
<div
class="navigation-sidebar"
v-if="sidebar.navigation">
<content-navigation
:mobile="true"
class="mobile-navigation__main"/>
:is-sidebar="true"
class="navigation-sidebar__main"/>
<div
class="mobile-navigation__close-button"
@click="hideMobileNavigation">
<cross class="mobile-navigation__close-icon"/>
class="navigation-sidebar__close-button"
@click="close">
<cross class="navigation-sidebar__close-icon"/>
</div>
</div>
</template>
@ -15,9 +17,13 @@
import Cross from '@/components/icons/Cross';
import ContentNavigation from '@/components/book-navigation/ContentNavigation';
import sidebarMixin from '@/mixins/sidebar';
import {meQuery} from '@/graphql/queries';
export default {
mixins: [sidebarMixin],
components: {
ContentNavigation,
Cross
@ -30,8 +36,8 @@
},
methods: {
hideMobileNavigation() {
this.$store.dispatch('showMobileNavigation', false);
close() {
this.closeSidebar('navigation');
}
},
@ -45,7 +51,7 @@
@import "@/styles/_variables.scss";
@import "@/styles/_mixins.scss";
.mobile-navigation {
.navigation-sidebar {
position: fixed;
left: 0;
right: 0;
@ -69,7 +75,8 @@
overflow-y: auto;
@include desktop {
display: none;
//display: none;
width: 285px;
}
&__main {

View File

@ -69,7 +69,7 @@
this.$apollo.mutate({
mutation: TOGGLE_SIDEBAR,
variables: {
open: false
profile: false
}
})
}

View File

@ -2,32 +2,34 @@
<div
v-click-outside="closeSidebar"
class="profile-sidebar"
v-if="sidebar.open">
v-if="sidebar.profile">
<a
class="profile-sidebar__close-link"
@click="closeSidebar">
@click="close">
<cross class="profile-sidebar__close-icon"/>
</a>
<profile-widget class="profile-sidebar__item"/>
<div
class="profile-sidebar__item"
@click="closeSidebar">
@click="close">
<router-link
to="/me/activity"
class="profile-sidebar__link">Meine Aktivitäten</router-link>
class="profile-sidebar__link">Meine Aktivitäten
</router-link>
</div>
<div class="profile-sidebar__item">
<h3 class="profile-sidebar__subtitle">Klasse</h3>
<class-selection-widget/>
<div @click="closeSidebar">
<div @click="close">
<router-link
:to="{name: 'my-class'}"
class="profile-sidebar__link">Klassenliste anzeigen</router-link>
class="profile-sidebar__link">Klassenliste anzeigen
</router-link>
</div>
</div>
<div
class="profile-sidebar__item"
@click="closeSidebar">
@click="close">
<router-link
:to="{name:'join-class'}"
data-cy="join-class-link"
@ -57,12 +59,19 @@
export default {
mixins: [sidebarMixin],
components: {
LogoutWidget,
ClassSelectionWidget,
ProfileWidget,
Cross
},
methods: {
close() {
this.closeSidebar('profile')
}
},
}
</script>

View File

@ -17,7 +17,9 @@ const writeLocalCache = cache => {
},
sidebar: {
__typename: 'Sidebar',
open: false
open: false,
profile: false,
navigation: false
},
helloEmail: {
__typename: 'HelloEmail',

View File

@ -1,3 +1,3 @@
mutation($open: Boolean!) {
toggleSidebar(open: $open) @client
mutation($sidebar: SidebarInput!) {
toggleSidebar(sidebar: $sidebar) @client
}

View File

@ -1,5 +1,7 @@
query Sidebar {
sidebar @client {
open
profile
navigation
}
}

View File

@ -16,9 +16,14 @@ export const resolvers = {
cache.writeQuery({query: HELLO_EMAIL, data});
return data.helloEmail;
},
toggleSidebar: (_, {open}, {cache}) => {
toggleSidebar: (_, {sidebar: {profile, navigation}}, {cache}) => {
const data = cache.readQuery({query: SIDEBAR});
data.sidebar.open = open;
if (typeof profile !== 'undefined') {
data.sidebar.profile = profile;
}
if (typeof navigation !== 'undefined') {
data.sidebar.navigation = navigation;
}
cache.writeQuery({query: SIDEBAR, data});
return data.sidebar;
}

View File

@ -1,6 +1,11 @@
import gql from 'graphql-tag';
export const typeDefs = gql`
type SidebarInput {
navigation: Boolean
profile: Boolean
}
type ScrollPosition {
scrollTo: String!
}
@ -12,13 +17,13 @@ export const typeDefs = gql`
type Sidebar {
open: Boolean!
navigation: Boolean
profile: Boolean
}
type Mutation {
scrollTo(scrollTo: String!): ScrollPosition
}
type Mutation {
helloEmail(email: String!): HelloEmail
toggleSidebar(sidebar: SidebarInput!): Sidebar
}
`;

View File

@ -2,12 +2,14 @@ import TOGGLE_SIDEBAR from '@/graphql/gql/local/mutations/toggleSidebar.gql';
export default {
methods: {
openSidebar() {
openSidebar(type) {
this.$nextTick(() => { // we don't want this to happen instantly, only almost instantly. Otherwise the click-outside-directive won't work
this.$apollo.mutate({
mutation: TOGGLE_SIDEBAR,
variables: {
open: true
sidebar: {
[type]: true
}
}
});
});

View File

@ -3,12 +3,14 @@ import TOGGLE_SIDEBAR from '@/graphql/gql/local/mutations/toggleSidebar.gql';
export default {
methods: {
closeSidebar() {
if (this.sidebar.open) {
closeSidebar(type) {
if (this.sidebar[type]) {
this.$apollo.mutate({
mutation: TOGGLE_SIDEBAR,
variables: {
open: false
sidebar: {
[type]: false
}
}
});
}
@ -23,7 +25,8 @@ export default {
data: () => ({
sidebar: {
open: false
profile: false,
navigation: false
}
})
}