Merge pull request #3842 from modoboa/task/contacts-pagination-and-categories

Contacts UI improvements
This commit is contained in:
Antoine Nguyen
2025-12-17 11:53:05 +01:00
committed by GitHub
2 changed files with 38 additions and 12 deletions
@@ -7,6 +7,9 @@
:items-length="totalContacts"
:loading="loading"
:search="search"
:page="currentPage"
:items-per-page="itemsPerPage"
:sort-by="sortBy"
item-value="pk"
show-expand
@update:options="fetchContacts"
@@ -208,6 +211,9 @@ const showForm = ref(false)
const showCategoriesForm = ref(false)
const preferences = ref({})
const loading = ref(false)
const currentPage = ref(1)
const itemsPerPage = ref(10)
const sortBy = ref([{ key: 'first_name', order: 'asc' }])
const headers = [
{ key: 'first_name', title: $gettext('First name') },
@@ -269,10 +275,10 @@ function closeCategoriesForm() {
selectedContact.value = null
}
function deleteContact(contact) {
contactsApi.deleteContact(contact.pk).then(() => {
fetchContacts()
})
async function deleteContact(contact) {
await contactsApi.deleteContact(contact.pk)
displayNotification({ msg: $gettext('Contact removed') })
await fetchContacts()
}
async function fetchAddressBook() {
@@ -286,13 +292,18 @@ async function fetchPreferences() {
}
async function fetchContacts(options) {
if (options) {
currentPage.value = options.page
itemsPerPage.value = options.itemsPerPage
sortBy.value = options.sortBy
}
const params = {
page: options?.page || 1,
page_size: options?.itemsPerPage || 10,
page: currentPage.value,
page_size: itemsPerPage.value,
...route.params,
}
if (options?.sortBy) {
params.ordering = options.sortBy
if (sortBy.value.length) {
params.ordering = sortBy.value
.map((item) => (item.order !== 'asc' ? `-${item.key}` : item.key))
.join(',')
}
+19 -4
View File
@@ -3,10 +3,10 @@
<div class="text-h5 ml-4">
{{ $gettext('Contacts') }}
</div>
<ContactList @edit-category="openCategoryForm" />
<ContactList @edit-category="openEditCategoryForm" />
<v-dialog v-model="showCategoryForm" persistent max-width="800px">
<CategoryForm
:category="contactsStore.currentCategory"
:category="selectedCategory"
@close="closeForm"
@added="fetchCategories"
@updated="fetchCategories"
@@ -17,7 +17,7 @@
<script setup>
import { computed, ref, watch } from 'vue'
import { useRouter } from 'vue-router'
import { useRouter, useRoute } from 'vue-router'
import { useGettext } from 'vue3-gettext'
import { useContactsStore, useLayoutStore } from '@/stores'
import contactsApi from '@/api/contacts'
@@ -25,11 +25,13 @@ import ContactList from '@/components/contacts/ContactList.vue'
import CategoryForm from '@/components/contacts/CategoryForm.vue'
const router = useRouter()
const route = useRoute()
const { $gettext } = useGettext()
const contactsStore = useContactsStore()
const layoutStore = useLayoutStore()
const categories = ref([])
const selectedCategory = ref(null)
const showCategoryForm = ref(false)
const leftMenuItems = computed(() => {
@@ -63,7 +65,13 @@ function openCategoryForm() {
showCategoryForm.value = true
}
function openEditCategoryForm() {
selectedCategory.value = contactsStore.currentCategory
showCategoryForm.value = true
}
function closeForm() {
selectedCategory.value = null
showCategoryForm.value = false
}
@@ -78,7 +86,7 @@ function filterByCategory(category) {
}
function fetchCategories() {
contactsApi.getCategories().then((resp) => {
return contactsApi.getCategories().then((resp) => {
categories.value = resp.data
})
}
@@ -88,4 +96,11 @@ fetchCategories()
watch(leftMenuItems, (value) => {
layoutStore.setLeftMenuItems(value)
})
watch(categories, () => {
if (route.params.category && !contactsStore.currentCategory) {
contactsStore.setCurrentCategory(
categories.value.find((item) => item.name === route.params.category)
)
}
})
</script>