Merge pull request #3819 from modoboa/fix/delete-active-filterset

Added possibility to deactivate active filter set.
This commit is contained in:
Antoine Nguyen
2025-11-28 15:35:33 +01:00
committed by GitHub
4 changed files with 80 additions and 37 deletions
+3
View File
@@ -70,6 +70,9 @@ export default {
activateFilterSet(filterSetName) {
return repository.post(`${resource}/filtersets/${filterSetName}/activate/`)
},
deactivateActiveFilterSet() {
return repository.post(`${resource}/filtersets/deactivate_active/`)
},
deleteFilterSet(filterSetName) {
return repository.delete(`${resource}/filtersets/${filterSetName}/`)
},
+61 -37
View File
@@ -4,7 +4,7 @@
{{ $gettext('Message filters') }}
</div>
<v-toolbar color="white" flat>
<v-toolbar color="white" flat class="px-4">
<v-autocomplete
v-model="currentFilterSet"
:label="$gettext('Select a filter set')"
@@ -55,10 +55,11 @@
color="primary"
:title="$gettext('Add new filter')"
class="mx-auto"
variant="outlined"
@click="showFilterForm = true"
>
<v-icon icon="mdi-plus" />
{{ $gettext('Add') }}
{{ $gettext('New') }}
</v-btn>
</div>
<v-data-table
@@ -100,19 +101,19 @@
</v-btn>
</template>
</div>
</div>
<v-dialog v-model="showFilterSetForm" max-width="600">
<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>
</div>
</template>
<script setup>
@@ -190,9 +191,9 @@ function getFilterSetName(filterSet) {
return result
}
function closeFilterSetForm() {
async function closeFilterSetForm() {
showFilterSetForm.value = false
fetchFilterSets()
await fetchFilterSets()
}
function closeFilterForm() {
@@ -201,27 +202,34 @@ function closeFilterForm() {
fetchFilters(currentFilterSet.value.name)
}
function fetchFilterSets() {
accountApi.getFilterSets().then((resp) => {
if (
resp.data.length > 0 &&
resp.data[0].active &&
resp.data[0].name === null
) {
// No filter is active
filterSets.value = resp.data.slice(1)
} else {
filterSets.value = resp.data
}
if (!currentFilterSet.value && route.params.filterset) {
for (const filterSet of filterSets.value) {
if (filterSet.name === route.params.filterset) {
currentFilterSet.value = filterSet
break
}
async function fetchFilterSets() {
const resp = await accountApi.getFilterSets()
if (
resp.data.length > 0 &&
resp.data[0].active &&
resp.data[0].name === null
) {
// No filter is active
filterSets.value = resp.data.slice(1)
} else {
filterSets.value = resp.data
}
if (route.params.filterset) {
for (const filterSet of filterSets.value) {
if (filterSet.name === route.params.filterset) {
currentFilterSet.value = filterSet
break
}
}
})
} else {
// Select first filter set
for (const filterSet of filterSets.value) {
if (filterSet.name) {
currentFilterSet.value = filterSet
break
}
}
}
}
function fetchFilters(filterSetName) {
@@ -285,14 +293,23 @@ async function moveFilterUp(filter) {
async function activateFilterSet(filterSet) {
await accountApi.activateFilterSet(filterSet.name)
await fetchFilterSets()
busStore.displayNotification({ msg: $gettext('Filter set activated') })
}
async function deactivateFilterSet() {
await accountApi.deactivateActiveFilterSet()
await fetchFilterSets()
busStore.displayNotification({
msg: $gettext('Active filter set deactivated'),
})
}
async function deleteFilterSet(filterSet) {
await accountApi.deleteFilterSet(filterSet.name)
busStore.displayNotification({ msg: $gettext('Filter set removed') })
currentFilterSet.value = null
fetchFilterSets()
await fetchFilterSets()
}
async function saveFilterSet() {
@@ -395,9 +412,16 @@ function getFilterSetActions() {
icon: 'mdi-check',
onClick: activateFilterSet,
})
} else {
result.push({
label: $gettext('Deactivate filter set'),
color: 'error',
icon: 'mdi-close',
onClick: deactivateFilterSet,
})
}
return result.concat(filterSetActions)
}
fetchFilterSets()
await fetchFilterSets()
</script>
+6
View File
@@ -96,6 +96,12 @@ class FilterSetViewSetTestCase(PatcherMixin, ModoAPITestCase):
resp = self.client.post(url)
self.assertEqual(resp.status_code, 200)
def test_deactivate_active(self):
self.authenticate()
url = reverse("v2:filterset-deactivate-active")
resp = self.client.post(url)
self.assertEqual(resp.status_code, 200)
def test_download(self):
self.authenticate()
url = reverse("v2:filterset-download", args=["unknown"])
+10
View File
@@ -99,6 +99,16 @@ class FilterSetViewSet(viewsets.ViewSet):
return response.Response({"error": str(err)}, status=400)
return response.Response()
@action(methods=["post"], detail=False)
def deactivate_active(self, request):
"""Deactivate the current active filterset."""
sclient = self.get_sieve_client(request)
try:
sclient.activatescript("")
except SieveClientError as err:
return response.Response({"error": str(err)}, status=400)
return response.Response()
@action(methods=["get"], detail=True)
def download(self, request, pk):
"""Download the content of an existing filter set."""