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:
parent
720d8d1e59
commit
67471d37b6
7 changed files with 184 additions and 118 deletions
70
src/App.vue
70
src/App.vue
|
@ -1,33 +1,91 @@
|
||||||
<template>
|
<template>
|
||||||
<div id="app">
|
<div id="app">
|
||||||
|
<v-window :touch="{ left: swipeLeft, right: swipeRight }">
|
||||||
<v-app id="inspire">
|
<v-app id="inspire">
|
||||||
<v-app id="sandbox">
|
<v-app id="sandbox">
|
||||||
<v-content>
|
<v-content>
|
||||||
<NavigationBar title="Fancy Flashcard"></NavigationBar>
|
<NavigationBar
|
||||||
<router-view />
|
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-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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
||||||
|
|
||||||
|
|
|
@ -11,37 +11,30 @@
|
||||||
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`
|
||||||
|
@ -50,30 +43,17 @@
|
||||||
|
|
||||||
<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>
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
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)
|
||||||
|
|
||||||
|
@ -8,15 +7,24 @@ Vue.use(VueRouter)
|
||||||
{
|
{
|
||||||
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
15
src/views/AddNewDeck.vue
Normal 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>
|
|
@ -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
15
src/views/Settings.vue
Normal 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>
|
Loading…
Reference in a new issue