fix deck selection

+ add settings and new deck route
+ add swipe to show/hide drawer

Co-authored-by: Niko Lockenvitz <nl@nikolockenvitz.de>
This commit is contained in:
Rene Fischer 2020-05-29 18:22:16 +02:00
parent 720d8d1e59
commit 67471d37b6
7 changed files with 184 additions and 118 deletions

View file

@ -1,33 +1,91 @@
<template> <template>
<div id="app"> <div id="app">
<v-app id="inspire"> <v-window :touch="{ left: swipeLeft, right: swipeRight }">
<v-app id="sandbox"> <v-app id="inspire">
<v-content> <v-app id="sandbox">
<NavigationBar title="Fancy Flashcard"></NavigationBar> <v-content>
<router-view /> <NavigationBar
</v-content> ref="navbar"
title="Fancy Flashcard"
v-bind:decks="decks"
v-bind:numberOfSelectedDecks="numberOfSelectedDecks"
v-bind:navBarList="navBarList"
></NavigationBar>
<router-view v-bind:decks="decks" v-bind:numberOfSelectedDecks="numberOfSelectedDecks" />
</v-content>
</v-app>
</v-app> </v-app>
</v-app> </v-window>
</div> </div>
</template> </template>
<script> <script>
import NavigationBar from "./components/layout/NavigationBar.vue"; import NavigationBar from "./components/layout/NavigationBar.vue";
import Footer from "./components/layout/Footer.vue";
export default { export default {
props: { props: {
title: String title: String
}, },
components: { components: {
NavigationBar, NavigationBar
Footer },
} data() {
return {
decks: [
{
id: 1,
deckname: "Test Deck 1",
selected: false
},
{
id: 2,
deckname: "Test Deck 2",
selected: false
}
],
navBarList: [
{
to: "/",
icon: "mdi-home",
title: "Home"
},
{
to: "/add",
icon: "mdi-plus",
title: "Add Deck"
},
{
to: "/settings",
icon: "mdi-cog",
title: "Settings"
},
{
to: "/about",
icon: "mdi-information",
title: "About"
}
],
};
},
computed: {
numberOfSelectedDecks() {
return this.decks.filter(deck => deck.selected).length;
},
},
methods: {
swipeLeft () {
this.$refs.navbar.hideDrawer();
},
swipeRight () {
this.$refs.navbar.showDrawer();
},
},
}; };
</script> </script>
<style> <style>
html, body { html,
body {
/* apply dark mode to scrollbar in firefox desktop */ /* apply dark mode to scrollbar in firefox desktop */
background-color: #000; background-color: #000;
} }

View file

@ -2,60 +2,50 @@
<div class="DeckSelection"> <div class="DeckSelection">
<v-subheader>Decks</v-subheader> <v-subheader>Decks</v-subheader>
<v-list> <v-list>
<v-list-item-group multiple color="indigo"> <v-list-item-group multiple color="indigo" v-model="deckModel">
<v-list-item <v-list-item
v-for="deck in decks" v-for="deck in decks"
:key="deck.id" :key="deck.id"
v-model="deck.selected" :value="deck.id"
:id="deck.id"
> >
<v-list-item-content> <v-list-item-content>
<v-list-item-title v-text="deck.deckname"></v-list-item-title> <v-list-item-title v-text="deck.deckname"></v-list-item-title>
</v-list-item-content> </v-list-item-content>
<v-list-item-icon v-bind:class="{ hidden: getNumberOfSelectedDecks()===0, visible: getNumberOfSelectedDecks()>0 }"> <v-list-item-icon v-bind:class="{ hidden: numberOfSelectedDecks===0, visible: numberOfSelectedDecks>0 }">
<v-icon v-if="deck.selected">mdi-check-box-outline</v-icon> <v-icon v-if="deck.selected">mdi-check-box-outline</v-icon>
<v-icon v-else>mdi-checkbox-blank-outline</v-icon> <v-icon v-else>mdi-checkbox-blank-outline</v-icon>
</v-list-item-icon> </v-list-item-icon>
</v-list-item> </v-list-item>
</v-list-item-group> </v-list-item-group>
</v-list> </v-list>
<v-btn class="mx-2" fab dark color="indigo"> <v-btn class="mx-2" fab dark color="indigo">
<v-icon v-if="getNumberOfSelectedDecks()>0" class="rotate-90">mdi-navigation</v-icon> <v-icon
<v-icon v-else>mdi-plus</v-icon> v-text="numberOfSelectedDecks === 0 ? 'mdi-plus' : 'mdi-navigation'"
:class="{ 'rotate-90': numberOfSelectedDecks > 0 }" />
</v-btn> </v-btn>
</div> </div>
</template> </template>
<script> <script>
export default { export default {
name: "DeckSelection", name: "DeckSelection",
created: function () {
this.$eventHub.$on("clearDeckSelection", () => {
this.setSelectedStateOfAllDecks(false);
});
this.$eventHub.$on("selectAllDecks", () => {
this.setSelectedStateOfAllDecks(true);
});
},
props: { props: {
decks: Array decks: Array,
numberOfSelectedDecks: Number,
}, },
methods: { computed: {
getNumberOfSelectedDecks () { deckModel: {
let numberOfSelectedDecks = 0; get () {
for (let deck of this.decks) { return this.decks.map((deck) => deck.selected ? deck.id : undefined).filter((id) => id !== undefined);
if (deck.selected) numberOfSelectedDecks++; },
set (newModel) {
this.decks.forEach((deck) => {
deck.selected = newModel.includes(deck.id);
});
} }
this.$eventHub.$emit("numberOfSelectedDecks", numberOfSelectedDecks); }
return numberOfSelectedDecks; }
},
setSelectedStateOfAllDecks (state) {
for (let deck of this.decks) {
deck.selected = state;
}
},
},
}; };
</script> </script>

View file

@ -11,69 +11,49 @@
overflow overflow
> >
<v-list> <v-list>
<v-list-item :to="'/'" link> <v-list-item v-for="navItem in navBarList" :key="navItem.to" :to="navItem.to" link>
<v-list-item-icon> <v-list-item-icon>
<v-icon>mdi-home</v-icon> <v-icon>{{navItem.icon}}</v-icon>
</v-list-item-icon> </v-list-item-icon>
<v-list-item-content> <v-list-item-content>
<v-list-item-title>Home</v-list-item-title> <v-list-item-title>{{navItem.title}}</v-list-item-title>
</v-list-item-content>
</v-list-item>
<v-list-item :to="'/about'" link>
<v-list-item-icon>
<v-icon>mdi-information</v-icon>
</v-list-item-icon>
<v-list-item-content>
<v-list-item-title>About</v-list-item-title>
</v-list-item-content> </v-list-item-content>
</v-list-item> </v-list-item>
</v-list> </v-list>
</v-navigation-drawer> </v-navigation-drawer>
<v-app-bar :clipped-left="primaryDrawer.clipped" app> <v-app-bar
<v-app-bar-nav-icon v-if="numberOfSelectedDecks===0" :clipped-left="primaryDrawer.clipped"
app
:class="{ 'indigo': numberOfSelectedDecks>0}"
>
<v-app-bar-nav-icon
v-if="numberOfSelectedDecks===0"
@click.stop="primaryDrawer.model = !primaryDrawer.model" @click.stop="primaryDrawer.model = !primaryDrawer.model"
></v-app-bar-nav-icon> ></v-app-bar-nav-icon>
<v-btn v-else icon <v-btn v-else icon @click="deselectAll">
@click="deselectAll"
>
<v-icon>mdi-close</v-icon> <v-icon>mdi-close</v-icon>
</v-btn> </v-btn>
<v-toolbar-title> <v-toolbar-title>
{{ numberOfSelectedDecks > 0 {{ numberOfSelectedDecks > 0
? `${numberOfSelectedDecks} deck${numberOfSelectedDecks === 1 ? "":"s"} selected` ? `${numberOfSelectedDecks} deck${numberOfSelectedDecks === 1 ? "":"s"} selected`
: title }} : title }}
</v-toolbar-title> </v-toolbar-title>
<v-spacer></v-spacer> <v-spacer></v-spacer>
<v-btn icon v-if="numberOfSelectedDecks===1" <v-btn icon v-if="numberOfSelectedDecks===1" @click="showInfoForSelectedDeck">
@click="showInfoForSelectedDeck"
>
<v-icon>mdi-information</v-icon> <v-icon>mdi-information</v-icon>
</v-btn> </v-btn>
<v-btn icon v-if="numberOfSelectedDecks>0" <v-btn icon v-if="numberOfSelectedDecks>0" @click="selectAll">
@click="selectAll"
>
<v-icon>mdi-checkbox-multiple-marked</v-icon> <v-icon>mdi-checkbox-multiple-marked</v-icon>
</v-btn> </v-btn>
<v-btn icon v-if="numberOfSelectedDecks>0" <v-btn icon v-if="numberOfSelectedDecks>0" @click="deleteSelected">
@click="deselectAll"
>
<v-icon>mdi-checkbox-multiple-blank-outline</v-icon>
</v-btn>
<v-btn icon v-if="numberOfSelectedDecks>0"
@click="deleteSelected"
>
<v-icon>mdi-delete</v-icon> <v-icon>mdi-delete</v-icon>
</v-btn> </v-btn>
</v-app-bar> </v-app-bar>
</div> </div>
</template> </template>
@ -81,38 +61,45 @@
<script> <script>
export default { export default {
name: "NavigationBar", name: "NavigationBar",
created: function () {
this.$eventHub.$on("numberOfSelectedDecks", (data) => {
this.numberOfSelectedDecks = data;
});
},
props: { props: {
title: String title: String,
decks: Array,
numberOfSelectedDecks: Number,
navBarList: Array
}, },
data: () => ({ data: () => ({
primaryDrawer: { primaryDrawer: {
model: null, model: false,
type: "temporary", type: "temporary",
clipped: true, clipped: true,
floating: false, floating: false,
mini: false mini: false
}, }
numberOfSelectedDecks: 0,
}), }),
methods: { methods: {
deselectAll () { deselectAll() {
this.$eventHub.$emit("clearDeckSelection"); this.decks.forEach(deck => {
deck.selected = false;
});
}, },
selectAll () { selectAll() {
this.$eventHub.$emit("selectAllDecks"); this.decks.forEach(deck => {
deck.selected = true;
});
}, },
deleteSelected () { deleteSelected() {
this.$eventHub.$emit("deleteSelectedDecks"); console.log("delete");
}, },
showInfoForSelectedDeck () { showInfoForSelectedDeck() {
this.$eventHub.$emit("showInformationForSelectedDeck"); console.log("show info");
}, },
}, showDrawer() {
this.primaryDrawer.model = true;
},
hideDrawer() {
this.primaryDrawer.model = false;
}
}
}; };
</script> </script>

View file

@ -1,22 +1,30 @@
import Vue from 'vue' import Vue from 'vue'
import VueRouter from 'vue-router' import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
Vue.use(VueRouter) Vue.use(VueRouter)
const routes = [ const routes = [
{ {
path: '/', path: '/',
name: 'Deckselection', name: 'Deckselection',
component: Home component: () => import('../views/Home.vue'),
props: true,
},
{
path: '/add',
name: 'Add New Deck',
component: () => import('../views/AddNewDeck.vue'),
props: true,
},
{
path: '/settings',
name: 'Settings',
component: () => import('../views/Settings.vue'),
}, },
{ {
path: '/about', path: '/about',
name: 'About', name: 'About',
// route level code-splitting component: () => import('../views/About.vue'),
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
} }
] ]

15
src/views/AddNewDeck.vue Normal file
View file

@ -0,0 +1,15 @@
<template>
<div class="settings">
<v-container fluid>
<v-row align="center" justify="center">
<v-col cols="10">
<span class="title">Fancy Flashcard</span>
<br>
<span>You will be able to add a new deck here.</span>
<br>
<a href="https://github.com/dhbw-ffc/ffc">https://github.com/dhbw-ffc/ffc</a>
</v-col>
</v-row>
</v-container>
</div>
</template>

View file

@ -1,6 +1,6 @@
<template> <template>
<div class="deckselection"> <div class="deckselection">
<DeckSelection v-bind:decks="decks"></DeckSelection> <DeckSelection v-bind:decks="decks" v-bind:numberOfSelectedDecks="numberOfSelectedDecks"></DeckSelection>
</div> </div>
</template> </template>
@ -8,23 +8,16 @@
import DeckSelection from '../components/deckselection/DeckSelection.vue' import DeckSelection from '../components/deckselection/DeckSelection.vue'
export default { export default {
name: 'App', name: 'App',
props: {
decks: Array,
numberOfSelectedDecks: Number
},
computed: {
},
components: { components: {
DeckSelection DeckSelection
}, },
data() {
return {
decks: [
{
id: 1,
deckname: "Test1"
},
{
id: 2,
deckname: "Test2"
}
]
};
},
} }
</script> </script>

15
src/views/Settings.vue Normal file
View file

@ -0,0 +1,15 @@
<template>
<div class="settings">
<v-container fluid>
<v-row align="center" justify="center">
<v-col cols="10">
<span class="title">Fancy Flashcard</span>
<br>
<span>You will be able to change your settings here.</span>
<br>
<a href="https://github.com/dhbw-ffc/ffc">https://github.com/dhbw-ffc/ffc</a>
</v-col>
</v-row>
</v-container>
</div>
</template>