Add popup options for saved filters

This commit is contained in:
kolaente 2021-01-28 21:49:39 +01:00
parent 2a153184d3
commit 21c6deb11c
Signed by: konrad
GPG Key ID: F40E70337AB24C9B
7 changed files with 237 additions and 243 deletions

View File

@ -6,32 +6,46 @@
<transition name="fade">
<div class="dropdown-menu" v-if="listSettingsOpen">
<div class="dropdown-content">
<router-link
:to="{ name: `${listRoutePrefix}.settings.edit`, params: { listId: list.id } }"
class="dropdown-item">
Edit this list
</router-link>
<router-link
:to="{ name: `${listRoutePrefix}.settings.background`, params: { listId: list.id } }"
v-if="backgroundsEnabled"
class="dropdown-item">
Set list background
</router-link>
<router-link
:to="{ name: `${listRoutePrefix}.settings.share`, params: { listId: list.id } }"
class="dropdown-item">
Share this list
</router-link>
<router-link
:to="{ name: `${listRoutePrefix}.settings.duplicate`, params: { listId: list.id } }"
class="dropdown-item">
Duplicate this list
</router-link>
<router-link
:to="{ name: `${listRoutePrefix}.settings.delete`, params: { listId: list.id } }"
class="dropdown-item">
Delete this list
</router-link>
<template v-if="isSavedFilter">
<router-link
:to="{ name: `${listRoutePrefix}.settings.edit`, params: { listId: list.id } }"
class="dropdown-item">
Edit this filter
</router-link>
<router-link
:to="{ name: `${listRoutePrefix}.settings.delete`, params: { listId: list.id } }"
class="dropdown-item">
Delete this filter
</router-link>
</template>
<template v-else>
<router-link
:to="{ name: `${listRoutePrefix}.settings.edit`, params: { listId: list.id } }"
class="dropdown-item">
Edit this list
</router-link>
<router-link
:to="{ name: `${listRoutePrefix}.settings.background`, params: { listId: list.id } }"
v-if="backgroundsEnabled"
class="dropdown-item">
Set list background
</router-link>
<router-link
:to="{ name: `${listRoutePrefix}.settings.share`, params: { listId: list.id } }"
class="dropdown-item">
Share this list
</router-link>
<router-link
:to="{ name: `${listRoutePrefix}.settings.duplicate`, params: { listId: list.id } }"
class="dropdown-item">
Duplicate this list
</router-link>
<router-link
:to="{ name: `${listRoutePrefix}.settings.delete`, params: { listId: list.id } }"
class="dropdown-item">
Delete this list
</router-link>
</template>
</div>
</div>
</transition>
@ -39,6 +53,8 @@
</template>
<script>
import {getSavedFilterIdFromListId} from '@/helpers/savedFilter'
export default {
name: 'list-settings-dropdown',
data() {
@ -59,11 +75,20 @@ export default {
return this.$store.state.config.enabledBackgroundProviders.length > 0
},
listRoutePrefix() {
let name = 'list'
if(this.$route.name.startsWith('list.')) {
return this.$route.name
name = this.$route.name
}
return 'list'
if(this.isSavedFilter) {
name = name.replace('list.', 'filter.')
}
return name
},
isSavedFilter() {
return getSavedFilterIdFromListId(this.list.id) > 0
},
},
}

View File

@ -35,6 +35,8 @@ import ListSettingBackground from '@/views/list/settings/background'
import ListSettingDuplicate from '@/views/list/settings/duplicate'
import ListSettingShare from '@/views/list/settings/share'
import ListSettingDelete from '@/views/list/settings/delete'
import FilterSettingEdit from '@/views/filters/settings/edit'
import FilterSettingDelete from '@/views/filters/settings/delete'
// Saved Filters
import CreateSavedFilter from '@/views/filters/CreateSavedFilter'
@ -63,12 +65,6 @@ const NewListComponent = () => ({
error: ErrorComponent,
timeout: 60000,
})
const EditListComponent = () => ({
component: import(/* webpackChunkName: "settings" */'../views/list/EditListView'),
loading: LoadingComponent,
error: ErrorComponent,
timeout: 60000,
})
// Namespace Handling
const NewNamespaceComponent = () => ({
component: import(/* webpackChunkName: "settings" */'../views/namespaces/NewNamespace'),
@ -181,11 +177,6 @@ export default new Router({
popup: NewListComponent,
}
},
{
path: '/lists/:id/edit',
name: 'list.edit',
component: EditListComponent,
},
{
path: '/tasks/:id',
name: 'task.detail',
@ -261,6 +252,16 @@ export default new Router({
name: 'list.list.settings.delete',
component: ListSettingDelete,
},
{
path: '/lists/:listId/settings/edit',
name: 'filter.list.settings.edit',
component: FilterSettingEdit,
},
{
path: '/lists/:listId/settings/delete',
name: 'filter.list.settings.delete',
component: FilterSettingDelete,
},
],
},
{

View File

@ -1,159 +0,0 @@
<template>
<div :class="{ 'is-loading': filterService.loading}" class="loader-container edit-list is-max-width-desktop">
<card title="Edit Saved Filter">
<form @submit.prevent="save()">
<div class="field">
<label class="label" for="listtext">Filter Name</label>
<div class="control">
<input
:class="{ 'disabled': filterService.loading}"
:disabled="filterService.loading"
@keyup.enter="save"
class="input"
id="listtext"
placeholder="The list title goes here..."
type="text"
v-focus
v-model="filter.title"/>
</div>
</div>
<div class="field">
<label class="label" for="listdescription">Description</label>
<div class="control">
<editor
:class="{ 'disabled': filterService.loading}"
:disabled="filterService.loading"
:preview-is-default="false"
id="listdescription"
placeholder="The lists description goes here..."
v-model="filter.description"
/>
</div>
</div>
<div class="field">
<label class="label" for="filters">Filters</label>
<div class="control">
<filters
:class="{ 'disabled': filterService.loading}"
:disabled="filterService.loading"
class="has-no-shadow has-no-border"
v-model="filters"
/>
</div>
</div>
</form>
<div class="field has-addons mt-4">
<div class="control is-fullwidth">
<x-button
@click="save()"
:loading="filterService.loading"
class="is-fullwidth">
Save
</x-button>
</div>
<div class="control">
<x-button
@click="showDeleteModal = true"
:loading="filterService.loading"
class="is-danger"
icon="trash-alt"
/>
</div>
</div>
</card>
<modal
@close="showDeleteModal = false"
@submit="() => deleteSavedFilter()"
v-if="showDeleteModal">
<span slot="header">Delete this saved filter</span>
<p slot="text">
Are you sure you want to delete this saved filter?
</p>
</modal>
</div>
</template>
<script>
import ErrorComponent from '../../components/misc/error'
import LoadingComponent from '../../components/misc/loading'
import SavedFilterModel from '@/models/savedFilter'
import SavedFilterService from '@/services/savedFilter'
import ListModel from '@/models/list'
import Filters from '@/components/list/partials/filters'
import {objectToSnakeCase} from '@/helpers/case'
export default {
name: 'EditFilter',
data() {
return {
filter: SavedFilterModel,
filterService: SavedFilterService,
filters: {
sort_by: ['done', 'id'],
order_by: ['asc', 'desc'],
filter_by: ['done'],
filter_value: ['false'],
filter_comparator: ['equals'],
filter_concat: 'and',
filter_include_nulls: true,
},
showDeleteModal: false,
}
},
components: {
Filters,
editor: () => ({
component: import(/* webpackChunkName: "editor" */ '../../components/input/editor'),
loading: LoadingComponent,
error: ErrorComponent,
timeout: 60000,
}),
},
created() {
this.filterService = new SavedFilterService()
this.loadSavedFilter()
},
watch: {
// call again the method if the route changes
'$route': 'loadSavedFilter',
},
methods: {
loadSavedFilter() {
// We assume the listId in the route is the pseudolist
const list = new ListModel({id: this.$route.params.id})
this.filter = new SavedFilterModel({id: list.getSavedFilterId()})
this.filterService.get(this.filter)
.then(r => {
this.filter = r
this.filters = objectToSnakeCase(this.filter.filters)
})
.catch(e => this.error(e, this))
},
save() {
this.filter.filters = this.filters
this.filterService.update(this.filter)
.then(r => {
this.$store.dispatch('namespaces/loadNamespaces')
this.success({message: 'The filter was saved successfully.'}, this)
this.filter = r
this.filters = objectToSnakeCase(this.filter.filters)
})
.catch(e => this.error(e, this))
},
deleteSavedFilter() {
this.filterService.delete(this.filter)
.then(() => {
this.$store.dispatch('namespaces/loadNamespaces')
this.success({message: 'The filter was deleted successfully.'}, this)
this.$router.push({name: 'namespaces.index'})
})
.catch(e => this.error(e, this))
},
},
}
</script>

View File

@ -0,0 +1,44 @@
<template>
<modal
@close="$router.back()"
@submit="deleteSavedFilter()"
>
<span slot="header">Delete this saved filter</span>
<p slot="text">
Are you sure you want to delete this saved filter?
</p>
</modal>
</template>
<script>
import SavedFilterModel from '@/models/savedFilter'
import SavedFilterService from '@/services/savedFilter'
import ListModel from '@/models/list'
export default {
name: 'filter-settings-delete',
data() {
return {
filterService: SavedFilterService,
}
},
created() {
this.filterService = new SavedFilterService()
},
methods: {
deleteSavedFilter() {
// We assume the listId in the route is the pseudolist
const list = new ListModel({id: this.$route.params.listId})
const filter = new SavedFilterModel({id: list.getSavedFilterId()})
this.filterService.delete(filter)
.then(() => {
this.$store.dispatch('namespaces/loadNamespaces')
this.success({message: 'The filter was deleted successfully.'}, this)
this.$router.push({name: 'namespaces.index'})
})
.catch(e => this.error(e, this))
},
},
}
</script>

View File

@ -0,0 +1,128 @@
<template>
<create-edit
title="Edit This Saved Filter"
primary-icon=""
primary-label="Save"
@primary="save"
tertary="Delete"
@tertary="$router.push({ name: 'filter.list.settings.delete', params: { id: $route.params.listId } })"
>
<form @submit.prevent="save()">
<div class="field">
<label class="label" for="title">Filter Title</label>
<div class="control">
<input
:class="{ 'disabled': filterService.loading}"
:disabled="filterService.loading"
@keyup.enter="save"
class="input"
id="title"
placeholder="The title goes here..."
type="text"
v-focus
v-model="filter.title"/>
</div>
</div>
<div class="field">
<label class="label" for="description">Description</label>
<div class="control">
<editor
:class="{ 'disabled': filterService.loading}"
:disabled="filterService.loading"
:preview-is-default="false"
id="description"
placeholder="The description goes here..."
v-model="filter.description"
/>
</div>
</div>
<div class="field">
<label class="label" for="filters">Filters</label>
<div class="control">
<filters
:class="{ 'disabled': filterService.loading}"
:disabled="filterService.loading"
class="has-no-shadow has-no-border"
v-model="filters"
/>
</div>
</div>
</form>
</create-edit>
</template>
<script>
import ErrorComponent from '@/components/misc/error'
import LoadingComponent from '@/components/misc/loading'
import CreateEdit from '@/components/misc/create-edit'
import SavedFilterModel from '@/models/savedFilter'
import SavedFilterService from '@/services/savedFilter'
import ListModel from '@/models/list'
import Filters from '@/components/list/partials/filters'
import {objectToSnakeCase} from '@/helpers/case'
export default {
name: 'filter-settings-edit',
data() {
return {
filter: SavedFilterModel,
filterService: SavedFilterService,
filters: {
sort_by: ['done', 'id'],
order_by: ['asc', 'desc'],
filter_by: ['done'],
filter_value: ['false'],
filter_comparator: ['equals'],
filter_concat: 'and',
filter_include_nulls: true,
},
showDeleteModal: false,
}
},
components: {
CreateEdit,
Filters,
editor: () => ({
component: import(/* webpackChunkName: "editor" */ '@/components/input/editor'),
loading: LoadingComponent,
error: ErrorComponent,
timeout: 60000,
}),
},
created() {
this.filterService = new SavedFilterService()
this.loadSavedFilter()
},
watch: {
// call again the method if the route changes
'$route': 'loadSavedFilter',
},
methods: {
loadSavedFilter() {
// We assume the listId in the route is the pseudolist
const list = new ListModel({id: this.$route.params.listId})
this.filter = new SavedFilterModel({id: list.getSavedFilterId()})
this.filterService.get(this.filter)
.then(r => {
this.filter = r
this.filters = objectToSnakeCase(this.filter.filters)
})
.catch(e => this.error(e, this))
},
save() {
this.filter.filters = this.filters
this.filterService.update(this.filter)
.then(r => {
this.$store.dispatch('namespaces/loadNamespaces')
this.success({message: 'The filter was saved successfully.'}, this)
this.filter = r
this.filters = objectToSnakeCase(this.filter.filters)
})
.catch(e => this.error(e, this))
},
},
}
</script>

View File

@ -1,20 +0,0 @@
<template>
<div :class="{ 'is-loading': listService.loading}" class="loader-container edit-list is-max-width-desktop">
<div class="notification is-warning" v-if="list.isArchived">
This list is archived.
It is not possible to create new or edit tasks or it.
</div>
</div>
</template>
<script>
export default {
name: 'EditList',
data() {
return {
}
},
}
</script>

View File

@ -1,25 +0,0 @@
<template>
<div>
<edit-filter v-if="isSavedFilter"/>
<edit-list v-else/>
</div>
</template>
<script>
import EditList from '@/views/list/EditList'
import EditFilter from '@/views/filters/EditSavedFilter'
import {mapState} from 'vuex'
import {getSavedFilterIdFromListId} from '@/helpers/savedFilter'
export default {
name: 'EditListView',
components: {
EditFilter,
EditList,
},
computed: mapState({
isSavedFilter: state => getSavedFilterIdFromListId(state.currentList.id) > 0
})
}
</script>