Added raw mode selector

This commit is contained in:
Antoine Nguyen
2024-06-22 19:44:48 +02:00
committed by Spitfireap
parent 6f6edecb93
commit 8a6308278c
5 changed files with 173 additions and 96 deletions
+3
View File
@@ -65,6 +65,9 @@ export default {
deleteFilterSet(filterSetName) {
return repository.delete(`${resource}/filtersets/${filterSetName}/`)
},
saveFilterSet(filterSetName, data) {
return repository.put(`${resource}/filtersets/${filterSetName}/`, data)
},
getFilterConditionTemplates() {
return repository.get(`${resource}/filtersets/condition_templates/`)
},
@@ -111,6 +111,7 @@
:label="arg.label"
color="primary"
:value="arg.value"
density="compact"
/>
</template>
</div>
+145 -96
View File
@@ -1,104 +1,129 @@
<template>
<v-toolbar flat>
<v-toolbar-title>{{ $gettext('Message filters') }}</v-toolbar-title>
</v-toolbar>
<div class="pa-4">
<div class="text-h6 font-weight-regular mb-4">{{ $gettext('Message filters') }}</div>
<div class="d-flex bg-white align-center pa-4">
<v-autocomplete
v-model="currentFilterSet"
:label="$gettext('Select a filter set')"
:items="filterSets"
:item-title="getFilterSetName"
return-object
variant="outlined"
hide-details
class="flex-grow-0"
style="width: 200px"
/>
<v-btn
color="primary"
icon="mdi-plus"
size="small"
class="mx-4"
@click="showFilterSetForm = true"
:title="$gettext('Add filter set')"
/>
<v-menu v-if="currentFilterSet">
<template v-slot:activator="{ props }">
<v-btn
append-icon="mdi-chevron-down"
v-bind="props"
size="small"
color="default"
>
{{ $gettext('Actions') }}
</v-btn>
</template>
<MenuItems
:items="getFilterSetActions()"
:obj="currentFilterSet"
<v-toolbar dense floating color="white">
<v-autocomplete
v-model="currentFilterSet"
:label="$gettext('Select a filter set')"
:items="filterSets"
:item-title="getFilterSetName"
return-object
variant="outlined"
hide-details
class="flex-grow-0"
style="width: 200px"
density="compact"
/>
</v-menu>
</div>
<v-btn
color="primary"
icon="mdi-plus"
size="small"
class="mx-4"
@click="showFilterSetForm = true"
:title="$gettext('Add filter set')"
/>
<v-menu v-if="currentFilterSet">
<template v-slot:activator="{ props }">
<v-btn
icon="mdi-dots-vertical"
v-bind="props"
size="small"
color="default"
>
</v-btn>
</template>
<MenuItems
:items="getFilterSetActions()"
:obj="currentFilterSet"
/>
</v-menu>
<div
v-if="currentFilterSet"
class="bg-white mt-4 pa-2"
>
<div class="d-flex align-center">
<v-spacer />
<v-btn
color="primary"
:title="$gettext('Add new filter')"
@click="showFilterForm = true"
<v-switch
v-if="currentFilterSet"
v-model="rawMode"
:label="$gettext('Raw mode')"
color="primary"
class="ml-4"
hide-details
/>
</v-toolbar>
<div
v-if="currentFilterSet"
class="bg-white mt-4 pa-2"
>
<v-icon icon="mdi-plus" />
{{ $gettext('Add') }}
</v-btn>
<template v-if="!rawMode">
<div class="d-flex align-center">
<v-spacer />
<v-btn
color="primary"
:title="$gettext('Add new filter')"
@click="showFilterForm = true"
>
<v-icon icon="mdi-plus" />
{{ $gettext('Add') }}
</v-btn>
</div>
<v-data-table
:headers="headers"
:items="filters"
:loading="loadingFilters"
>
<template #[`item.enabled`]="{ item }">
{{ $yesno(item.enabled) }}
</template>
<template #[`item.filter_actions`]="{ item }">
<v-menu offset-y>
<template #activator="{ props }">
<v-btn
icon="mdi-dots-horizontal"
variant="text"
v-bind="props"
>
</v-btn>
</template>
<MenuItems :items="getFilterActions(item)" :obj="item" />
</v-menu>
</template>
</v-data-table>
</template>
<template v-else>
<v-textarea
v-model="filterSetRawContent"
variant="outlined"
auto-grow
/>
<v-btn
color="success"
@click="saveFilterSet"
:loading="saving"
>
{{ $gettext('Save') }}
</v-btn>
</template>
</div>
</div>
<v-data-table
:headers="headers"
:items="filters"
<v-dialog
v-model="showFilterSetForm"
max-width="600"
>
<template #[`item.enabled`]="{ item }">
{{ $yesno(item.enabled) }}
</template>
<template #[`item.filter_actions`]="{ item }">
<v-menu offset-y>
<template #activator="{ props }">
<v-btn
icon="mdi-dots-horizontal"
variant="text"
v-bind="props"
>
</v-btn>
</template>
<MenuItems :items="getFilterActions(item)" :obj="item" />
</v-menu>
</template>
</v-data-table>
</div>
<FilterSetForm
@close="closeFilterSetForm"
/>
</v-dialog>
<v-dialog
v-model="showFilterSetForm"
max-width="600"
>
<FilterSetForm
@close="closeFilterSetForm"
/>
</v-dialog>
<v-dialog
v-model="showFilterForm"
max-width="800"
>
<FilterForm
v-if="currentFilterSet"
:filter-set="currentFilterSet.name"
:filter="selectedFilter"
@close="closeFilterForm"
/>
</v-dialog>
<v-dialog
v-model="showFilterForm"
max-width="800"
>
<FilterForm
v-if="currentFilterSet"
:filter-set="currentFilterSet.name"
:filter="selectedFilter"
@close="closeFilterForm"
/>
</v-dialog>
</template>
<script setup>
@@ -118,7 +143,11 @@ const { $gettext } = useGettext()
const filterSets = ref([])
const filters = ref([])
const filterSetRawContent = ref('')
const currentFilterSet = ref()
const loadingFilters = ref(false)
const rawMode = ref(false)
const saving = ref(false)
const selectedFilter = ref(null)
const showFilterSetForm = ref(false)
const showFilterForm = ref(false)
@@ -142,6 +171,16 @@ watch(currentFilterSet, (value) => {
}
})
watch(rawMode, (value) => {
if (value) {
accountApi.downloadFilterSet(currentFilterSet.value.name).then(resp => {
filterSetRawContent.value = resp.data
})
} else {
fetchFilters(currentFilterSet.value.name)
}
})
function getFilterSetName(filterSet) {
let result = filterSet.name
if (filterSet.active) {
@@ -176,8 +215,10 @@ function fetchFilterSets() {
}
function fetchFilters(filterSetName) {
loadingFilters.value = true
accountApi.getFilters(filterSetName).then(resp => {
filters.value = resp.data
loadingFilters.value = false
})
}
@@ -219,6 +260,14 @@ async function deleteFilterSet(filterSet) {
fetchFilterSets()
}
async function saveFilterSet() {
const data = { content: filterSetRawContent.value }
saving.value = true
await accountApi.saveFilterSet(currentFilterSet.value.name, data)
saving.value = false
busStore.displayNotification({ msg: $gettext('Filter set updated') })
}
async function downloadFilterSet(filterSet) {
const resp = await accountApi.downloadFilterSet(filterSet.name)
const blob = new Blob([resp.data], { type: 'text/plain' })
@@ -294,9 +343,9 @@ fetchFilterSets()
</script>
<style scoped>
.v-toolbar {
background-color: #f7f8fa !important;
}
/* .v-toolbar {
background-color: white !important;
} */
.v-tabs {
background-color: #f7f8fa !important;
}
@@ -16,6 +16,11 @@ class FilterSetSerializer(serializers.Serializer):
active = serializers.BooleanField(default=False)
class FilterSetContentSerializer(serializers.Serializer):
content = serializers.CharField()
class ConditionSerializer(serializers.Serializer):
name = serializers.CharField()
+19
View File
@@ -51,6 +51,25 @@ class FilterSetViewSet(viewsets.ViewSet):
)
return response.Response(serializer.validated_data, 201)
@extend_schema(
request=serializers.FilterSetContentSerializer,
responses=serializers.FilterSetContentSerializer,
)
def update(self, request, pk):
"""Update filter set content."""
sclient = self.get_sieve_client(request)
try:
fset = sclient.getscript(pk)
except SieveClientError:
return response.Response(status=404)
serializer = serializers.FilterSetContentSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
try:
sclient.pushscript(pk, serializer.validated_data["content"])
except SieveClientError as e:
error = str(e)
return response.Response(serializer.validated_data)
@action(methods=["post"], detail=True)
def activate(self, request, pk):
"""Activate an existing filter set."""