feat: create new popup component to handle popups generally

This commit is contained in:
kolaente 2021-11-02 21:59:14 +01:00
parent 9250f4e76b
commit 86efb07f09
Signed by untrusted user: konrad
GPG Key ID: F40E70337AB24C9B
6 changed files with 88 additions and 88 deletions

View File

@ -6,39 +6,42 @@
>
{{ $t('filters.clear') }}
</x-button>
<filters
:class="{'is-open': visibleInternal}"
class="filter-popup"
v-model="value"
ref="filters"
/>
<popup>
<template #trigger="{toggle}">
<x-button
@click.prevent.stop="toggle()"
type="secondary"
icon="filter"
>
{{ $t('filters.title') }}
</x-button>
</template>
<template #default>
<filters
v-model="value"
ref="filters"
/>
</template>
</popup>
</template>
<script>
import {closeWhenClickedOutside} from '@/helpers/closeWhenClickedOutside'
import Filters from '../../../components/list/partials/filters'
import {getDefaultParams} from '../../tasks/mixins/taskList'
import Popup from '../../misc/popup'
export default {
name: 'filter-popup',
components: {
Popup,
Filters,
},
props: {
modelValue: {
required: true,
},
visible: {
type: Boolean,
default: false,
},
},
emits: ['update:modelValue'],
data() {
return {
visibleInternal: false,
}
},
computed: {
value: {
get() {
@ -65,12 +68,6 @@ export default {
return JSON.stringify(filterParams) !== JSON.stringify(def)
},
},
mounted() {
document.addEventListener('click', this.hidePopup)
},
beforeUnmount() {
document.removeEventListener('click', this.hidePopup)
},
watch: {
modelValue: {
handler(value) {
@ -78,43 +75,11 @@ export default {
},
immediate: true,
},
visible() {
this.visibleInternal = !this.visibleInternal
},
},
methods: {
hidePopup(e) {
if (!this.visibleInternal) {
return
}
closeWhenClickedOutside(e, this.$refs.filters.$el, () => {
this.visibleInternal = false
})
},
clearFilters() {
this.value = {...getDefaultParams()}
},
},
}
</script>
<style lang="scss">
.filter-popup {
transition: opacity $transition;
opacity: 0;
height: 0;
overflow: hidden;
position: absolute;
top: 2rem;
margin: 0 !important;
border-width: 0 !important;
&.is-open {
opacity: 1;
height: auto;
margin: 1rem 0 !important;
border-width: 1px !important;
}
}
</style>

View File

@ -0,0 +1,63 @@
<template>
<slot name="trigger" :isOpen="open" :toggle="toggle"></slot>
<div class="popup" :class="{'is-open': open}">
<slot ref="popupContent"/>
</div>
</template>
<script>
import {closeWhenClickedOutside} from '@/helpers/closeWhenClickedOutside'
import {onBeforeUnmount, onMounted, ref} from 'vue'
export default {
setup() {
const open = ref(false)
const popupContent = ref(null)
const toggle = () => {
open.value = !open.value
}
const hidePopup = e => {
if (!open.value) {
return
}
closeWhenClickedOutside(e, popupContent.$el, () => {
open.value = false
})
}
onMounted(() => {
document.addEventListener('click', hidePopup)
})
onBeforeUnmount(() => {
document.removeEventListener('click', hidePopup)
})
return {
open,
toggle,
}
},
}
</script>
<style scoped lang="scss">
.popup {
transition: opacity $transition;
opacity: 0;
height: 0;
overflow: hidden;
position: absolute;
top: 1rem;
margin: 0 !important;
&.is-open {
opacity: 1;
height: auto;
margin: 1rem 0 !important;
}
}
</style>

View File

@ -1,16 +1,14 @@
import TaskCollectionService from '@/services/taskCollection'
// FIXME: merge with DEFAULT_PARAMS in filters.vue
const DEFAULT_PARAMS = {
export const getDefaultParams = () => ({
sort_by: ['position', 'id'],
order_by: ['asc', 'desc'],
filter_by: ['done'],
filter_value: ['false'],
filter_comparator: ['equals'],
filter_concat: 'and',
}
export const getDefaultParams = () => ({...DEFAULT_PARAMS})
})
/**
* This mixin provides a base set of methods and properties to get tasks on a list.

View File

@ -2,16 +2,9 @@
<div class="kanban-view">
<div class="filter-container" v-if="isSavedFilter">
<div class="items">
<x-button
@click.prevent.stop="toggleFilterPopup"
icon="filter"
type="secondary"
>
{{ $t('filters.title') }}
</x-button>
<filter-popup
:visible="showFilters"
v-model="params"
@update:modelValue="loadBuckets"
/>
</div>
</div>
@ -300,7 +293,6 @@ export default {
filter_comparator: [],
filter_concat: 'and',
},
showFilters: false,
}
},
created() {
@ -359,10 +351,6 @@ export default {
},
methods: {
toggleFilterPopup() {
this.showFilters = !this.showFilters
},
loadBuckets() {
// Prevent trying to load buckets if the task popup view is active
if (this.$route.name !== 'list.kanban') {

View File

@ -41,15 +41,7 @@
v-if="!showTaskSearch"
/>
</div>
<x-button
@click.prevent.stop="showTaskFilter = !showTaskFilter"
type="secondary"
icon="filter"
>
{{ $t('filters.title') }}
</x-button>
<filter-popup
:visible="showTaskFilter"
v-model="params"
@update:modelValue="loadTasks()"
/>
@ -154,6 +146,7 @@ import FilterPopup from '@/components/list/partials/filter-popup.vue'
import {HAS_TASKS} from '@/store/mutation-types'
import Nothing from '@/components/misc/nothing.vue'
import Pagination from '@/components/misc/pagination.vue'
import Popup from '@/components/misc/popup'
import draggable from 'vuedraggable'
import {calculateItemPosition} from '../../../helpers/calculateItemPosition'
@ -197,6 +190,7 @@ export default {
taskList,
],
components: {
Popup,
Nothing,
FilterPopup,
SingleTaskInList,

View File

@ -3,21 +3,13 @@
<div class="filter-container">
<div class="items">
<x-button
@click.prevent.stop="() => {showActiveColumnsFilter = !showActiveColumnsFilter; showTaskFilter = false}"
@click.prevent.stop="showActiveColumnsFilter = !showActiveColumnsFilter"
icon="th"
type="secondary"
>
{{ $t('list.table.columns') }}
</x-button>
<x-button
@click.prevent.stop="() => {showTaskFilter = !showTaskFilter; showActiveColumnsFilter = false}"
icon="filter"
type="secondary"
>
{{ $t('filters.title') }}
</x-button>
<filter-popup
:visible="showTaskFilter"
v-model="params"
@update:modelValue="loadTasks()"
/>