Restructure components
This commit is contained in:
175
src/components/list/partials/background-settings.vue
Normal file
175
src/components/list/partials/background-settings.vue
Normal file
@ -0,0 +1,175 @@
|
||||
<template>
|
||||
<div
|
||||
class="card list-background-setting loader-container"
|
||||
v-if="uploadBackgroundEnabled || unsplashBackgroundEnabled"
|
||||
:class="{ 'is-loading': backgroundService.loading}">
|
||||
<header class="card-header">
|
||||
<p class="card-header-title">
|
||||
Set list background
|
||||
</p>
|
||||
</header>
|
||||
<div class="card-content">
|
||||
<div class="content" v-if="uploadBackgroundEnabled">
|
||||
<input
|
||||
type="file"
|
||||
ref="backgroundUploadInput"
|
||||
@change="uploadBackground"
|
||||
class="is-hidden"
|
||||
accept="image/*"
|
||||
/>
|
||||
<a
|
||||
class="button is-primary"
|
||||
:class="{'is-loading': backgroundUploadService.loading}"
|
||||
@click="$refs.backgroundUploadInput.click()"
|
||||
>
|
||||
Choose a background from your pc
|
||||
</a>
|
||||
</div>
|
||||
<div class="content" v-if="unsplashBackgroundEnabled">
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Search for a background..."
|
||||
class="input is-expanded"
|
||||
v-model="backgroundSearchTerm"
|
||||
@keyup="() => newBackgroundSearch()"
|
||||
:class="{'is-loading': backgroundService.loading}"
|
||||
/>
|
||||
<p class="unsplash-link"><a href="https://unsplash.com" target="_blank">Powered by Unsplash</a></p>
|
||||
<div class="image-search-result">
|
||||
<a
|
||||
@click="() => setBackground(im.id)"
|
||||
class="image"
|
||||
v-for="im in backgroundSearchResult"
|
||||
:style="{'background-image': `url(${backgroundThumbs[im.id]})`}"
|
||||
:key="im.id">
|
||||
<a class="info" :href="`https://unsplash.com/@${im.info.author}`">
|
||||
{{ im.info.authorName }}
|
||||
</a>
|
||||
</a>
|
||||
</div>
|
||||
<a
|
||||
v-if="backgroundSearchResult.length > 0"
|
||||
class="button is-primary is-centered is-load-more-button is-outlined noshadow"
|
||||
@click="() => searchBackgrounds(currentPage + 1)"
|
||||
:disabled="backgroundService.loading"
|
||||
>
|
||||
<template v-if="backgroundService.loading">
|
||||
Loading...
|
||||
</template>
|
||||
<template v-else>
|
||||
Load more photos
|
||||
</template>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import BackgroundUnsplashService from '../../../services/backgroundUnsplash'
|
||||
import BackgroundUploadService from '../../../services/backgroundUpload'
|
||||
import {CURRENT_LIST} from '../../../store/mutation-types'
|
||||
|
||||
export default {
|
||||
name: 'background-settings',
|
||||
data() {
|
||||
return {
|
||||
backgroundSearchTerm: '',
|
||||
backgroundSearchResult: [],
|
||||
backgroundService: null,
|
||||
backgroundThumbs: {},
|
||||
currentPage: 1,
|
||||
backgroundSearchTimeout: null,
|
||||
|
||||
backgroundUploadService: null,
|
||||
}
|
||||
},
|
||||
props: {
|
||||
listId: {
|
||||
default: 0,
|
||||
required: true,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
unsplashBackgroundEnabled() {
|
||||
return this.$store.state.config.enabledBackgroundProviders.includes('unsplash')
|
||||
},
|
||||
uploadBackgroundEnabled() {
|
||||
return this.$store.state.config.enabledBackgroundProviders.includes('upload')
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.backgroundService = new BackgroundUnsplashService()
|
||||
this.backgroundUploadService = new BackgroundUploadService()
|
||||
// Show the default collection of backgrounds
|
||||
this.newBackgroundSearch()
|
||||
},
|
||||
methods: {
|
||||
newBackgroundSearch() {
|
||||
if (!this.unsplashBackgroundEnabled) {
|
||||
return
|
||||
}
|
||||
// This is an extra method to reset a few things when searching to not break loading more photos.
|
||||
this.$set(this, 'backgroundSearchResult', [])
|
||||
this.$set(this, 'backgroundThumbs', {})
|
||||
this.searchBackgrounds()
|
||||
},
|
||||
searchBackgrounds(page = 1) {
|
||||
|
||||
if (this.backgroundSearchTimeout !== null) {
|
||||
clearTimeout(this.backgroundSearchTimeout)
|
||||
}
|
||||
|
||||
// We're using the timeout to not search on every keypress but with a 300ms delay.
|
||||
// If another key is pressed within these 300ms, the last search request is dropped and a new one is scheduled.
|
||||
this.backgroundSearchTimeout = setTimeout(() => {
|
||||
this.currentPage = page
|
||||
this.backgroundService.getAll({}, {s: this.backgroundSearchTerm, p: page})
|
||||
.then(r => {
|
||||
this.backgroundSearchResult = this.backgroundSearchResult.concat(r)
|
||||
r.forEach(b => {
|
||||
this.backgroundService.thumb(b)
|
||||
.then(t => {
|
||||
this.$set(this.backgroundThumbs, b.id, t)
|
||||
})
|
||||
})
|
||||
})
|
||||
.catch(e => {
|
||||
this.error(e, this)
|
||||
})
|
||||
}, 300)
|
||||
},
|
||||
setBackground(backgroundId) {
|
||||
// Don't set a background if we're in the process of setting one
|
||||
if (this.backgroundService.loading) {
|
||||
return
|
||||
}
|
||||
|
||||
this.backgroundService.update({id: backgroundId, listId: this.listId})
|
||||
.then(l => {
|
||||
this.$store.commit(CURRENT_LIST, l)
|
||||
this.$store.commit('namespaces/setListInNamespaceById', l)
|
||||
this.success({message: 'The background has been set successfully!'}, this)
|
||||
})
|
||||
.catch(e => {
|
||||
this.error(e, this)
|
||||
})
|
||||
},
|
||||
uploadBackground() {
|
||||
if (this.$refs.backgroundUploadInput.files.length === 0) {
|
||||
return
|
||||
}
|
||||
|
||||
this.backgroundUploadService.create(this.listId, this.$refs.backgroundUploadInput.files[0])
|
||||
.then(l => {
|
||||
this.$store.commit(CURRENT_LIST, l)
|
||||
this.$store.commit('namespaces/setListInNamespaceById', l)
|
||||
this.success({message: 'The background has been set successfully!'}, this)
|
||||
})
|
||||
.catch(e => {
|
||||
this.error(e, this)
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
152
src/components/list/partials/filters.vue
Normal file
152
src/components/list/partials/filters.vue
Normal file
@ -0,0 +1,152 @@
|
||||
<template>
|
||||
<div class="card filters">
|
||||
<div class="card-content">
|
||||
<div class="field">
|
||||
<label class="label">Show Done Tasks</label>
|
||||
<div class="control">
|
||||
<fancycheckbox @change="setDoneFilter" v-model="filters.done">
|
||||
Show Done Tasks
|
||||
</fancycheckbox>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label">Due Date</label>
|
||||
<div class="control">
|
||||
<flat-pickr
|
||||
class="input"
|
||||
:config="flatPickerConfig"
|
||||
placeholder="Due Date Range"
|
||||
v-model="filters.dueDate"
|
||||
@on-close="setDueDateFilter"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Fancycheckbox from '../../input/fancycheckbox'
|
||||
import flatPickr from 'vue-flatpickr-component'
|
||||
import 'flatpickr/dist/flatpickr.css'
|
||||
|
||||
export default {
|
||||
name: 'filters',
|
||||
components: {
|
||||
Fancycheckbox,
|
||||
flatPickr,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
params: {
|
||||
sort_by: [],
|
||||
order_by: [],
|
||||
filter_by: [],
|
||||
filter_value: [],
|
||||
filter_comparator: [],
|
||||
},
|
||||
filters: {
|
||||
done: false,
|
||||
dueDate: '',
|
||||
},
|
||||
flatPickerConfig: {
|
||||
altFormat: 'j M Y H:i',
|
||||
altInput: true,
|
||||
dateFormat: 'Y-m-d H:i',
|
||||
enableTime: true,
|
||||
time_24hr: true,
|
||||
mode: 'range',
|
||||
},
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.params = this.value
|
||||
this.prepareDone()
|
||||
},
|
||||
props: {
|
||||
value: {
|
||||
required: true,
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
value(newVal) {
|
||||
this.$set(this, 'params', newVal)
|
||||
this.prepareDone()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
change() {
|
||||
this.$emit('input', this.params)
|
||||
this.$emit('change', this.params)
|
||||
},
|
||||
prepareDone() {
|
||||
// Set filters.done based on params
|
||||
if(typeof this.params.filter_by !== 'undefined') {
|
||||
let foundDone = false
|
||||
this.params.filter_by.forEach((f, i) => {
|
||||
if (f === 'done') {
|
||||
foundDone = i
|
||||
}
|
||||
})
|
||||
if (foundDone === false) {
|
||||
this.filters.done = true
|
||||
}
|
||||
}
|
||||
},
|
||||
setDoneFilter() {
|
||||
if (this.filters.done) {
|
||||
for (const i in this.params.filter_by) {
|
||||
if (this.params.filter_by[i] === 'done') {
|
||||
this.params.filter_by.splice(i, 1)
|
||||
this.params.filter_comparator.splice(i, 1)
|
||||
this.params.filter_value.splice(i, 1)
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.params.filter_by.push('done')
|
||||
this.params.filter_comparator.push('equals')
|
||||
this.params.filter_value.push('false')
|
||||
}
|
||||
this.change()
|
||||
},
|
||||
setDueDateFilter() {
|
||||
// Only filter if we have a start and end due date
|
||||
if (this.filters.dueDate !== '') {
|
||||
|
||||
const parts = this.filters.dueDate.split(' to ')
|
||||
|
||||
if(parts.length < 2) {
|
||||
return
|
||||
}
|
||||
|
||||
// Check if we already have values in params and only update them if we do
|
||||
let foundStart = false
|
||||
let foundEnd = false
|
||||
this.params.filter_by.forEach((f, i) => {
|
||||
if (f === 'due_date' && this.params.filter_comparator[i] === 'greater_equals') {
|
||||
foundStart = true
|
||||
this.params.filter_value[i] = +new Date(parts[0]) / 1000
|
||||
}
|
||||
if (f === 'due_date' && this.params.filter_comparator[i] === 'less_equals') {
|
||||
foundEnd = true
|
||||
this.params.filter_value[i] = +new Date(parts[1]) / 1000
|
||||
}
|
||||
})
|
||||
|
||||
if (!foundStart) {
|
||||
this.params.filter_by.push('due_date')
|
||||
this.params.filter_comparator.push('greater_equals')
|
||||
this.params.filter_value.push(+new Date(parts[0]) / 1000)
|
||||
}
|
||||
if (!foundEnd) {
|
||||
this.params.filter_by.push('due_date')
|
||||
this.params.filter_comparator.push('less_equals')
|
||||
this.params.filter_value.push(+new Date(parts[1]) / 1000)
|
||||
}
|
||||
this.change()
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
Reference in New Issue
Block a user