Skip to content

Commit

Permalink
feat(webui): navigation drawer for sort/filter
Browse files Browse the repository at this point in the history
preliminary to #283
  • Loading branch information
gotson committed Aug 25, 2020
1 parent 9440654 commit 28598cb
Show file tree
Hide file tree
Showing 9 changed files with 290 additions and 146 deletions.
53 changes: 53 additions & 0 deletions komga-webui/src/components/FilterDrawer.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<template>
<v-navigation-drawer
v-model="display"
right
fixed
temporary
disable-route-watcher
class="fill-height"
>
<slot></slot>

<template v-if="$slots.filter">
<v-divider/>
<v-subheader>FILTER</v-subheader>
</template>
<slot name="filter"></slot>

<template v-if="$slots.sort">
<v-divider/>
<v-subheader>SORT</v-subheader>
</template>
<slot name="sort"></slot>

</v-navigation-drawer>
</template>

<script lang="ts">
import Vue from 'vue'
export default Vue.extend({
name: 'FilterDrawer',
data: () => {
return {
display: false,
}
},
props: {
value: Boolean,
},
watch: {
value (val) {
this.display = val
},
display (val) {
!val && this.$emit('input', false)
},
},
})
</script>

<style scoped>
</style>
Original file line number Diff line number Diff line change
@@ -1,13 +1,5 @@
<template>
<v-menu offset-y>
<template v-slot:activator="{on}">
<v-btn icon v-on="on">
<v-icon :color="filterCustom ? 'secondary' : null"
>mdi-filter-variant
</v-icon>
</v-btn>
</template>
<v-list>
<v-list dense>
<div v-for="(f, key) in filtersOptions"
:key="key"
>
Expand All @@ -29,26 +21,14 @@
</v-list-item-title>
</v-list-item>
</div>

<template v-if="filterCustom">
<v-divider/>

<v-list-item @click="clearAll" dense>
<v-list-item-icon>
<v-icon>mdi-close</v-icon>
</v-list-item-icon>
<v-list-item-title>Clear</v-list-item-title>
</v-list-item>
</template>
</v-list>
</v-menu>
</template>

<script lang="ts">
import Vue from 'vue'
export default Vue.extend({
name: 'FilterMenuButton',
name: 'FilterList',
props: {
filtersOptions: {
type: Object as () => FiltersOptions,
Expand All @@ -59,24 +39,7 @@ export default Vue.extend({
required: true,
},
},
computed: {
filterCustom (): boolean {
let r = false
for (const [key, value] of Object.entries(this.filtersActive)) {
if (!this.$_.isEmpty(value)) r = true
}
return r
},
},
methods: {
clearAll () {
let r = this.$_.cloneDeep(this.filtersActive)
for (const key of Object.keys(r)) {
r[key] = []
}
this.$emit('update:filtersActive', r)
},
click (key: string, value: string) {
let r = this.$_.cloneDeep(this.filtersActive)
if (r[key].includes(value)) this.$_.pull(r[key], (value))
Expand Down
86 changes: 86 additions & 0 deletions komga-webui/src/components/FilterPanels.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<template>
<v-expansion-panels accordion multiple flat tile hover>
<v-expansion-panel
v-for="(f, key) in filtersOptions"
:key="key"
>
<v-expansion-panel-header>
<v-icon
color="secondary"
style="max-width: 24px"
class="mr-2"
@click.stop="clear(key)"
>{{ groupActive(key) ? 'mdi-checkbox-marked' : '' }}
</v-icon>
{{ f.name }}
</v-expansion-panel-header>
<v-expansion-panel-content class="no-padding">
<v-list dense>
<v-list-item v-for="v in f.values"
:key="v"
@click.stop="click(key, v)"
>
<v-list-item-icon>
<v-icon v-if="filtersActive[key].includes(v)" color="secondary">
mdi-checkbox-marked
</v-icon>
<v-icon v-else>
mdi-checkbox-blank-outline
</v-icon>
</v-list-item-icon>
<v-list-item-title class="text-capitalize">
{{ v.toString().toLowerCase().replace('_', ' ') }}
</v-list-item-title>
</v-list-item>
</v-list>
</v-expansion-panel-content>
</v-expansion-panel>
</v-expansion-panels>
</template>

<script lang="ts">
import Vue from 'vue'
export default Vue.extend({
name: 'FilterPanels',
props: {
filtersOptions: {
type: Object as () => FiltersOptions,
required: true,
},
filtersActive: {
type: Object as () => FiltersActive,
required: true,
},
},
methods: {
clear (key: string) {
let r = this.$_.cloneDeep(this.filtersActive)
r[key] = []
this.$emit('update:filtersActive', r)
},
groupActive (key: string): boolean {
for (let v of this.filtersOptions[key].values) {
if (this.filtersActive[key].includes(v)) {
return true
}
}
return false
},
click (key: string, value: string) {
let r = this.$_.cloneDeep(this.filtersActive)
if (r[key].includes(value)) this.$_.pull(r[key], (value))
else r[key].push(value)
this.$emit('update:filtersActive', r)
},
},
})
</script>

<style>
.no-padding .v-expansion-panel-content__wrap {
padding: 0;
}
</style>
57 changes: 57 additions & 0 deletions komga-webui/src/components/SortList.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<template>
<v-list dense>
<v-list-item v-for="(item, index) in sortOptions"
:key="index"
@click="setSort(item)"
>
<v-list-item-icon>
<v-icon color="secondary" v-if="item.key === sortActive.key && sortActive.order === 'asc'">
mdi-chevron-up
</v-icon>
<v-icon color="secondary" v-if="item.key === sortActive.key && sortActive.order === 'desc'">
mdi-chevron-down
</v-icon>
</v-list-item-icon>
<v-list-item-title>{{ item.name }}</v-list-item-title>
</v-list-item>
</v-list>
</template>

<script lang="ts">
import Vue from 'vue'
export default Vue.extend({
name: 'SortList',
props: {
sortOptions: {
type: Array,
required: true,
},
sortDefault: {
type: Object,
required: true,
},
sortActive: {
type: Object,
required: true,
},
},
methods: {
setSort (sort: SortOption) {
if (this.sortActive.key === sort.key) {
if (this.sortActive.order === 'desc') {
this.$emit('update:sortActive', { key: sort.key, order: 'asc' })
} else {
this.$emit('update:sortActive', { key: sort.key, order: 'desc' })
}
} else {
this.$emit('update:sortActive', { key: sort.key, order: 'desc' })
}
},
},
})
</script>

<style scoped>
</style>
71 changes: 0 additions & 71 deletions komga-webui/src/components/SortMenuButton.vue

This file was deleted.

5 changes: 5 additions & 0 deletions komga-webui/src/functions/filter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export function sortOrFilterActive (sortActive: SortActive, sortDefault: SortActive, filters: FiltersActive): boolean {
const sortCustom = sortActive.key !== sortDefault.key || sortActive.order !== sortDefault.order
const filterCustom = Object.keys(filters).some(x => filters[x].length !== 0)
return sortCustom || filterCustom
}

0 comments on commit 28598cb

Please sign in to comment.