|
|
|
@ -1,5 +1,5 @@ |
|
|
|
|
<template> |
|
|
|
|
<div class="message-list"> |
|
|
|
|
<div class="message-list flex flex-col"> |
|
|
|
|
<SectionHeader :title="title"> |
|
|
|
|
<BaseButton |
|
|
|
|
icon="email-plus" |
|
|
|
@ -46,6 +46,7 @@ |
|
|
|
|
icon="inbox" |
|
|
|
|
type="black" |
|
|
|
|
@click="showInbox" |
|
|
|
|
class="w-full md:w-auto" |
|
|
|
|
/> |
|
|
|
|
|
|
|
|
|
<BaseButton |
|
|
|
@ -53,6 +54,7 @@ |
|
|
|
|
icon="email-unread" |
|
|
|
|
type="black" |
|
|
|
|
@click="showUnread" |
|
|
|
|
class="w-full md:w-auto" |
|
|
|
|
/> |
|
|
|
|
|
|
|
|
|
<BaseButton |
|
|
|
@ -60,6 +62,7 @@ |
|
|
|
|
icon="sent" |
|
|
|
|
type="black" |
|
|
|
|
@click="showSent" |
|
|
|
|
class="w-full md:w-auto" |
|
|
|
|
/> |
|
|
|
|
|
|
|
|
|
<BaseButton |
|
|
|
@ -69,9 +72,11 @@ |
|
|
|
|
icon="tag-outline" |
|
|
|
|
type="black" |
|
|
|
|
@click="showInboxByTag(tag)" |
|
|
|
|
class="w-full md:w-auto" |
|
|
|
|
/> |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<div class="hidden md:block overflow-x-auto"> |
|
|
|
|
<DataTable |
|
|
|
|
ref="dtMessages" |
|
|
|
|
v-model:selection="selectedItems" |
|
|
|
@ -92,6 +97,7 @@ |
|
|
|
|
striped-rows |
|
|
|
|
@page="onPage" |
|
|
|
|
@sort="sortingChanged" |
|
|
|
|
class="w-full table-auto" |
|
|
|
|
> |
|
|
|
|
<template #header> |
|
|
|
|
<form |
|
|
|
@ -160,6 +166,7 @@ |
|
|
|
|
:header="t('Send date')" |
|
|
|
|
:sortable="true" |
|
|
|
|
field="sendDate" |
|
|
|
|
class="truncate w-24 md:w-auto" |
|
|
|
|
> |
|
|
|
|
<template #body="slotProps"> |
|
|
|
|
{{ abbreviatedDatetime(slotProps.data.sendDate) }} |
|
|
|
@ -177,6 +184,88 @@ |
|
|
|
|
</Column> |
|
|
|
|
</DataTable> |
|
|
|
|
</div> |
|
|
|
|
<!-- List for small screens with pagination --> |
|
|
|
|
<div class="block md:hidden"> |
|
|
|
|
<ul class="space-y-4"> |
|
|
|
|
<li |
|
|
|
|
v-for="item in paginatedItems" |
|
|
|
|
:key="item.id" |
|
|
|
|
class="bg-white shadow-md rounded-lg p-4" |
|
|
|
|
> |
|
|
|
|
<div class="flex items-center space-x-4"> |
|
|
|
|
<BaseAvatarList |
|
|
|
|
v-if="showingInbox && item.sender" |
|
|
|
|
:users="[item.sender]" |
|
|
|
|
/> |
|
|
|
|
<div |
|
|
|
|
v-else-if="showingInbox && !item.sender" |
|
|
|
|
class="text-sm text-gray-600" |
|
|
|
|
v-text="t('No sender')" |
|
|
|
|
/> |
|
|
|
|
<BaseAvatarList |
|
|
|
|
v-else |
|
|
|
|
:users="mapReceiverMixToUsers(item)" |
|
|
|
|
/> |
|
|
|
|
<div class="flex-1"> |
|
|
|
|
<div v-if="showingInbox && item.sender" class="font-bold text-lg"> |
|
|
|
|
{{ item.sender.name }} |
|
|
|
|
</div> |
|
|
|
|
<div v-if="showingInbox && item.sender" class="text-sm text-gray-600"> |
|
|
|
|
{{ item.sender.email }} |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
<div class="mt-4"> |
|
|
|
|
<div class="text-sm font-bold">{{ t('Title') }}:</div> |
|
|
|
|
<BaseAppLink |
|
|
|
|
class="text-base text-blue-600" |
|
|
|
|
:to="{ name: 'MessageShow', query: { id: item['@id'] } }" |
|
|
|
|
> |
|
|
|
|
{{ item.title }} |
|
|
|
|
</BaseAppLink> |
|
|
|
|
</div> |
|
|
|
|
<div v-if="findMyReceiver(item)?.tags.length" class="mt-2"> |
|
|
|
|
<div class="text-sm font-bold">{{ t('Tags') }}:</div> |
|
|
|
|
<div> |
|
|
|
|
<BaseTag |
|
|
|
|
v-for="tag in findMyReceiver(item)?.tags" |
|
|
|
|
:key="tag.id" |
|
|
|
|
:label="tag.tag" |
|
|
|
|
type="info" |
|
|
|
|
/> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
<div class="mt-2"> |
|
|
|
|
<div class="text-sm font-bold">{{ t('Send date') }}:</div> |
|
|
|
|
<div class="text-base text-gray-500">{{ abbreviatedDatetime(item.sendDate) }}</div> |
|
|
|
|
</div> |
|
|
|
|
<div class="mt-4 flex space-x-2"> |
|
|
|
|
<BaseButton |
|
|
|
|
icon="delete" |
|
|
|
|
size="small" |
|
|
|
|
type="danger" |
|
|
|
|
@click="showDlgConfirmDeleteSingle(item)" |
|
|
|
|
/> |
|
|
|
|
</div> |
|
|
|
|
</li> |
|
|
|
|
</ul> |
|
|
|
|
<div class="flex justify-between items-center mt-4"> |
|
|
|
|
<BaseButton |
|
|
|
|
:disabled="isPrevDisabled" |
|
|
|
|
@click="prevPage" |
|
|
|
|
icon="back" |
|
|
|
|
type="black" |
|
|
|
|
/> |
|
|
|
|
<span>{{ t('Page') }} {{ currentPage }} {{ t('of') }} {{ totalPages }} ({{ totalItems }} {{ t('messages') }})</span> |
|
|
|
|
<BaseButton |
|
|
|
|
:disabled="isNextDisabled" |
|
|
|
|
@click="nextPage" |
|
|
|
|
icon="next" |
|
|
|
|
type="black" |
|
|
|
|
/> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
</template> |
|
|
|
|
|
|
|
|
|
<script setup> |
|
|
|
@ -310,6 +399,42 @@ const rowClass = (data) => { |
|
|
|
|
|
|
|
|
|
let fetchPayload = {} |
|
|
|
|
|
|
|
|
|
const rows = ref(10) |
|
|
|
|
const currentPage = ref(1) |
|
|
|
|
|
|
|
|
|
const totalPages = computed(() => { |
|
|
|
|
return Math.ceil(totalItems.value / rows.value) |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
const paginatedItems = computed(() => { |
|
|
|
|
if (!items.value.length) { |
|
|
|
|
return [] |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return items.value |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
function nextPage() { |
|
|
|
|
if (currentPage.value < totalPages.value) { |
|
|
|
|
currentPage.value++ |
|
|
|
|
fetchPayload.page = currentPage.value |
|
|
|
|
fetchPayload.itemsPerPage = rows.value |
|
|
|
|
loadMessages(false) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function prevPage() { |
|
|
|
|
if (currentPage.value > 1) { |
|
|
|
|
currentPage.value-- |
|
|
|
|
fetchPayload.page = currentPage.value |
|
|
|
|
fetchPayload.itemsPerPage = rows.value |
|
|
|
|
loadMessages(false) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const isPrevDisabled = computed(() => currentPage.value === 1) |
|
|
|
|
const isNextDisabled = computed(() => currentPage.value === totalPages.value) |
|
|
|
|
|
|
|
|
|
function loadMessages(reset = true) { |
|
|
|
|
if (reset) { |
|
|
|
|
store.dispatch("message/resetList") |
|
|
|
@ -450,12 +575,14 @@ async function deleteMessage(message) { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function showDlgConfirmDeleteSingle({ data }) { |
|
|
|
|
function showDlgConfirmDeleteSingle(dataOrItem) { |
|
|
|
|
const item = dataOrItem.data || dataOrItem |
|
|
|
|
|
|
|
|
|
confirm.require({ |
|
|
|
|
header: t("Confirmation"), |
|
|
|
|
message: t("Are you sure you want to delete %s?", [data.title]), |
|
|
|
|
message: t("Are you sure you want to delete %s?", [item.title]), |
|
|
|
|
accept: async () => { |
|
|
|
|
await deleteMessage(data) |
|
|
|
|
await deleteMessage(item) |
|
|
|
|
}, |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|