Minor: Format code

pull/4840/head
Angel Fernando Quiroz Campos 2 years ago
parent 3bd2005529
commit 24616c2972
  1. 134
      assets/vue/App.vue
  2. 48
      assets/vue/components/Login.vue
  3. 7
      assets/vue/components/layout/TopbarLoggedIn.vue
  4. 237
      assets/vue/views/message/MessageList.vue
  5. 174
      assets/vue/views/message/MessageShow.vue

@ -4,16 +4,14 @@
v-if="!platformConfigurationStore.isLoading" v-if="!platformConfigurationStore.isLoading"
:show-breadcrumb="route.meta.showBreadcrumb" :show-breadcrumb="route.meta.showBreadcrumb"
> >
<Toast <Toast position="top-center">
position="top-center"
>
<template #message="slotProps"> <template #message="slotProps">
<span <span
:class="{ :class="{
'mdi-close-outline': 'error' === slotProps.message.severity, 'mdi-close-outline': 'error' === slotProps.message.severity,
'mdi-information-outline': 'info' === slotProps.message.severity, 'mdi-information-outline': 'info' === slotProps.message.severity,
'mdi-check-outline': 'success' === slotProps.message.severity, 'mdi-check-outline': 'success' === slotProps.message.severity,
'mdi-alert-outline': 'warn' === slotProps.message.severity 'mdi-alert-outline': 'warn' === slotProps.message.severity,
}" }"
class="p-toast-message-icon mdi" class="p-toast-message-icon mdi"
/> />
@ -40,110 +38,101 @@
</template> </template>
<script setup> <script setup>
import {computed, onMounted, provide, ref, watch, watchEffect} from 'vue'; import { computed, onMounted, provide, ref, watch, watchEffect } from "vue"
import {useRoute, useRouter} from 'vue-router'; import { useRoute, useRouter } from "vue-router"
import {DefaultApolloClient} from '@vue/apollo-composable'; import { DefaultApolloClient } from "@vue/apollo-composable"
import {ApolloClient, createHttpLink, InMemoryCache} from '@apollo/client/core'; import { ApolloClient, createHttpLink, InMemoryCache } from "@apollo/client/core"
import {useStore} from "vuex"; import { useStore } from "vuex"
import axios from "axios"; import axios from "axios"
import {isEmpty} from "lodash"; import { isEmpty } from "lodash"
import ConfirmDialog from "primevue/confirmdialog"; import ConfirmDialog from "primevue/confirmdialog"
import Toast from 'primevue/toast'; import { useToast } from "primevue/usetoast"
import { useToast } from 'primevue/usetoast';
import { useSecurityStore } from "./store/securityStore" import { useSecurityStore } from "./store/securityStore"
import { usePlatformConfig } from "./store/platformConfig"
const apolloClient = new ApolloClient({ const apolloClient = new ApolloClient({
link: createHttpLink({ link: createHttpLink({
uri: '/api/graphql', uri: "/api/graphql",
}), }),
cache: new InMemoryCache(), cache: new InMemoryCache(),
}); })
provide(DefaultApolloClient, apolloClient); provide(DefaultApolloClient, apolloClient)
const route = useRoute(); const route = useRoute()
const router = useRouter(); const router = useRouter()
const toast = useToast(); const toast = useToast()
const layout = computed( const layout = computed(() => {
() => { const queryParams = new URLSearchParams(window.location.search)
const queryParams = new URLSearchParams(window.location.search);
if (queryParams.has('lp') if (queryParams.has("lp") || (queryParams.has("origin") && "learnpath" === queryParams.get("origin"))) {
|| (queryParams.has('origin') && 'learnpath' === queryParams.get('origin')) return "EmptyLayout"
) {
return 'EmptyLayout';
} }
return `${router.currentRoute.value.meta.layout ?? 'Dashboard'}Layout`; return `${router.currentRoute.value.meta.layout ?? "Dashboard"}Layout`
} })
);
const legacyContainer = ref(null); const legacyContainer = ref(null)
watch( watch(route, () => {
route,
() => {
if (legacyContainer.value) { if (legacyContainer.value) {
legacyContainer.value.innerHTML = ''; legacyContainer.value.innerHTML = ""
} }
} })
);
watchEffect(() => { watchEffect(() => {
if (!legacyContainer.value) { if (!legacyContainer.value) {
return; return
} }
const content = document.querySelector("#sectionMainContent"); const content = document.querySelector("#sectionMainContent")
if (content) { if (content) {
legacyContainer.value.appendChild(content); legacyContainer.value.appendChild(content)
const chEditors = window.chEditors || [] const chEditors = window.chEditors || []
chEditors.forEach((editorConfig) => tinymce.init(editorConfig)) chEditors.forEach((editorConfig) => tinymce.init(editorConfig))
content.style.display = "block"; content.style.display = "block"
} }
}); })
watchEffect( watchEffect(async () => {
async () => {
try { try {
const component = `${route.meta.layout}.vue`; const component = `${route.meta.layout}.vue`
layout.value = component?.default || 'Dashboard'; layout.value = component?.default || "Dashboard"
} catch (e) { } catch (e) {
layout.value = 'Dashboard'; layout.value = "Dashboard"
}
} }
); })
const user = ref({}); const user = ref({})
let isAuthenticated = false; let isAuthenticated = false
if (!isEmpty(window.user)) { if (!isEmpty(window.user)) {
user.value = window.user; user.value = window.user
isAuthenticated = true; isAuthenticated = true
} }
const store = useStore(); const store = useStore()
const securityStore = useSecurityStore() const securityStore = useSecurityStore()
const payload = {isAuthenticated, user}; const payload = { isAuthenticated, user }
store.dispatch('security/onRefresh', payload); store.dispatch("security/onRefresh", payload)
securityStore.user = window.user securityStore.user = window.user
onMounted(() => { onMounted(() => {
const app = document.getElementById('app'); const app = document.getElementById("app")
if (!(app && app.dataset.flashes)) { if (!(app && app.dataset.flashes)) {
return; return
} }
const flashes = JSON.parse(app.dataset.flashes); const flashes = JSON.parse(app.dataset.flashes)
for (const key in flashes) { for (const key in flashes) {
for (const flashText in flashes[key]) { for (const flashText in flashes[key]) {
@ -151,34 +140,33 @@ onMounted(() => {
severity: key, severity: key,
detail: flashes[key][flashText], detail: flashes[key][flashText],
life: 3500, life: 3500,
}); })
} }
} }
}); })
axios.interceptors.response.use( axios.interceptors.response.use(
undefined, undefined,
(error) => new Promise(() => { (error) =>
new Promise(() => {
if (401 === error.response.status) { if (401 === error.response.status) {
toast.add({ toast.add({
severity: 'warn', severity: "warn",
detail: error.response.data.error, detail: error.response.data.error,
life: 3500, life: 3500,
}); })
} else if (500 === error.response.status) { } else if (500 === error.response.status) {
toast.add({ toast.add({
severity: 'warn', severity: "warn",
detail: error.response.data.detail, detail: error.response.data.detail,
life: 3500, life: 3500,
});
}
throw error;
}) })
); }
import {usePlatformConfig} from './store/platformConfig'; throw error
}),
)
const platformConfigurationStore = usePlatformConfig(); const platformConfigurationStore = usePlatformConfig()
platformConfigurationStore.initialize(); platformConfigurationStore.initialize()
</script> </script>

@ -71,52 +71,52 @@
</template> </template>
<script setup> <script setup>
import {useStore} from 'vuex'; import { useStore } from "vuex"
import {computed, ref} from "vue"; import { computed, ref } from "vue"
import {useRoute, useRouter} from "vue-router"; import { useRoute, useRouter } from "vue-router"
import Button from 'primevue/button'; import Button from "primevue/button"
import InputText from 'primevue/inputtext'; import InputText from "primevue/inputtext"
import Password from 'primevue/password'; import Password from "primevue/password"
import InputSwitch from 'primevue/inputswitch'; import InputSwitch from "primevue/inputswitch"
import {useI18n} from "vue-i18n"; import { useI18n } from "vue-i18n"
import { useSecurityStore } from "../store/securityStore" import { useSecurityStore } from "../store/securityStore"
const route = useRoute(); const route = useRoute()
const router = useRouter(); const router = useRouter()
const store = useStore(); const store = useStore()
const {t} = useI18n(); const { t } = useI18n()
const securityStore = useSecurityStore() const securityStore = useSecurityStore()
const login = ref(''); const login = ref("")
const password = ref(''); const password = ref("")
const remember = ref(false); const remember = ref(false)
const isLoading = computed(() => store.getters['security/isLoading']); const isLoading = computed(() => store.getters["security/isLoading"])
let redirect = route.query.redirect; let redirect = route.query.redirect
if (store.getters["security/isAuthenticated"]) { if (store.getters["security/isAuthenticated"]) {
if (typeof redirect !== "undefined") { if (typeof redirect !== "undefined") {
router.push({path: redirect.toString()}); router.push({ path: redirect.toString() })
} else { } else {
router.replace({name: 'Home'}); router.replace({ name: "Home" })
} }
} }
async function performLogin() { async function performLogin() {
let payload = {login: login.value, password: password.value}; let payload = { login: login.value, password: password.value }
let redirect = route.query.redirect; let redirect = route.query.redirect
await store.dispatch("security/login", payload); await store.dispatch("security/login", payload)
if (!store.getters["security/hasError"]) { if (!store.getters["security/hasError"]) {
securityStore.user = store.state["security/user"] securityStore.user = store.state["security/user"]
if (typeof redirect !== "undefined") { if (typeof redirect !== "undefined") {
await router.push({path: redirect.toString()}); await router.push({ path: redirect.toString() })
} else { } else {
// router.replace({path: "/home"}); // router.replace({path: "/home"});
window.location.href = '/home'; window.location.href = "/home"
} }
} }
} }

@ -30,8 +30,8 @@
:badge="btnInboxBadge" :badge="btnInboxBadge"
:class="{ 'item-button--unread': btnInboxBadge }" :class="{ 'item-button--unread': btnInboxBadge }"
:icon="chamiloIconToClass['inbox']" :icon="chamiloIconToClass['inbox']"
class="item-button"
badge-class="item-button__badge" badge-class="item-button__badge"
class="item-button"
icon-class="item-button__icon" icon-class="item-button__icon"
link link
unstyled unstyled
@ -85,7 +85,7 @@ const router = useRouter()
const platformConfigStore = usePlatformConfig() const platformConfigStore = usePlatformConfig()
const messageRelUserStore = useMessageRelUserStore() const messageRelUserStore = useMessageRelUserStore()
const notification = useNotification(); const notification = useNotification()
const btnTicketsOnClick = () => { const btnTicketsOnClick = () => {
const { cid, sid, gid } = useCidReq() const { cid, sid, gid } = useCidReq()
@ -118,6 +118,5 @@ const headerLogo = headerLogoPath
const btnInboxBadge = computed(() => (messageRelUserStore.countUnread > 9 ? "9+" : messageRelUserStore.countUnread)) const btnInboxBadge = computed(() => (messageRelUserStore.countUnread > 9 ? "9+" : messageRelUserStore.countUnread))
messageRelUserStore.findUnreadCount() messageRelUserStore.findUnreadCount().catch((e) => notification.showErrorNotification(e))
.catch((e) => notification.showErrorNotification(e))
</script> </script>

@ -1,10 +1,24 @@
<template> <template>
<div class="flex gap-4 items-center"> <div class="flex gap-4 items-center">
<h2 class="mr-auto" v-text="title" /> <h2
class="mr-auto"
v-text="title"
/>
<BaseButton icon="email-plus" only-icon type="black" @click="goToCompose" /> <BaseButton
icon="email-plus"
only-icon
type="black"
@click="goToCompose"
/>
<BaseButton :disabled="isLoading" icon="refresh" only-icon type="black" @click="refreshMessages" /> <BaseButton
:disabled="isLoading"
icon="refresh"
only-icon
type="black"
@click="refreshMessages"
/>
<BaseButton <BaseButton
:disabled="0 === selectedItems.length || isLoading" :disabled="0 === selectedItems.length || isLoading"
@ -23,7 +37,11 @@
@click="mToggleMessagesList" @click="mToggleMessagesList"
/> />
<BaseMenu id="course-messages-list-tmenu" ref="mMessageList" :model="mItemsMarkAs" /> <BaseMenu
id="course-messages-list-tmenu"
ref="mMessageList"
:model="mItemsMarkAs"
/>
</div> </div>
<hr /> <hr />
@ -31,11 +49,26 @@
<div class="grid grid-cols-1 md:grid-cols-5 gap-4"> <div class="grid grid-cols-1 md:grid-cols-5 gap-4">
<div class="space-y-4"> <div class="space-y-4">
<div class="flex md:flex-col gap-2"> <div class="flex md:flex-col gap-2">
<BaseButton :label="t('Inbox')" icon="inbox" type="black" @click="showInbox" /> <BaseButton
:label="t('Inbox')"
icon="inbox"
type="black"
@click="showInbox"
/>
<BaseButton :label="t('Unread')" icon="email-unread" type="black" @click="showUnread" /> <BaseButton
:label="t('Unread')"
icon="email-unread"
type="black"
@click="showUnread"
/>
<BaseButton :label="t('Sent')" icon="sent" type="black" @click="showSent" /> <BaseButton
:label="t('Sent')"
icon="sent"
type="black"
@click="showSent"
/>
<BaseButton <BaseButton
v-for="tag in tags" v-for="tag in tags"
@ -84,7 +117,12 @@
{{ slotProps.data.title }} {{ slotProps.data.title }}
</div> </div>
<BaseTag v-for="tag in findMyReceiver(slotProps.data)?.tags" :key="tag.id" :label="tag.tag" type="info" /> <BaseTag
v-for="tag in findMyReceiver(slotProps.data)?.tags"
:key="tag.id"
:label="tag.tag"
type="info"
/>
</template> </template>
</Column> </Column>
<Column :header="t('Send date')"> <Column :header="t('Send date')">
@ -94,7 +132,12 @@
</Column> </Column>
<Column :header="t('Actions')"> <Column :header="t('Actions')">
<template #body="slotProps"> <template #body="slotProps">
<BaseButton icon="delete" size="small" type="danger" @click="showDlgConfirmDeleteSingle(slotProps)" /> <BaseButton
icon="delete"
size="small"
type="danger"
@click="showDlgConfirmDeleteSingle(slotProps)"
/>
</template> </template>
</Column> </Column>
</DataTable> </DataTable>
@ -103,35 +146,35 @@
</template> </template>
<script setup> <script setup>
import { computed, onMounted, ref } from "vue"; import { computed, onMounted, ref } from "vue"
import { useStore } from "vuex"; import { useStore } from "vuex"
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n"
import { useRoute, useRouter } from "vue-router"; import { useRoute, useRouter } from "vue-router"
import { useRelativeDatetime } from "../../composables/formatDate"; import { useRelativeDatetime } from "../../composables/formatDate"
import BaseButton from "../../components/basecomponents/BaseButton.vue"; import BaseButton from "../../components/basecomponents/BaseButton.vue"
import BaseMenu from "../../components/basecomponents/BaseMenu.vue"; import BaseMenu from "../../components/basecomponents/BaseMenu.vue"
import BaseUserAvatar from "../../components/basecomponents/BaseUserAvatar.vue"; import BaseUserAvatar from "../../components/basecomponents/BaseUserAvatar.vue"
import BaseTag from "../../components/basecomponents/BaseTag.vue"; import BaseTag from "../../components/basecomponents/BaseTag.vue"
import DataTable from "primevue/datatable"; import DataTable from "primevue/datatable"
import Column from "primevue/column"; import Column from "primevue/column"
import { useConfirm } from "primevue/useconfirm"; import { useConfirm } from "primevue/useconfirm"
import { useQuery } from "@vue/apollo-composable"; import { useQuery } from "@vue/apollo-composable"
import { MESSAGE_STATUS_DELETED, MESSAGE_TYPE_INBOX } from "../../components/message/constants"; import { MESSAGE_STATUS_DELETED, MESSAGE_TYPE_INBOX } from "../../components/message/constants"
import { GET_USER_MESSAGE_TAGS } from "../../graphql/queries/MessageTag"; import { GET_USER_MESSAGE_TAGS } from "../../graphql/queries/MessageTag"
import { useNotification } from "../../composables/notification"; import { useNotification } from "../../composables/notification"
import { useMessageRelUserStore } from "../../store/messageRelUserStore" import { useMessageRelUserStore } from "../../store/messageRelUserStore"
const route = useRoute(); const route = useRoute()
const router = useRouter(); const router = useRouter()
const store = useStore(); const store = useStore()
const { t } = useI18n(); const { t } = useI18n()
const confirm = useConfirm(); const confirm = useConfirm()
const notification = useNotification(); const notification = useNotification()
const messageRelUserStore = useMessageRelUserStore() const messageRelUserStore = useMessageRelUserStore()
const user = computed(() => store.getters["security/getUser"]); const user = computed(() => store.getters["security/getUser"])
const mItemsMarkAs = ref([ const mItemsMarkAs = ref([
{ {
@ -144,15 +187,15 @@ const mItemsMarkAs = ref([
return undefined return undefined
} }
myReceiver.read = true; myReceiver.read = true
return store.dispatch("messagereluser/update", myReceiver); return store.dispatch("messagereluser/update", myReceiver)
}) })
Promise.all(promises) Promise.all(promises)
.then(() => messageRelUserStore.findUnreadCount()) .then(() => messageRelUserStore.findUnreadCount())
.catch((e) => notification.showErrorNotification(e)) .catch((e) => notification.showErrorNotification(e))
.finally(() => selectedItems.value = []) .finally(() => (selectedItems.value = []))
}, },
}, },
{ {
@ -165,76 +208,76 @@ const mItemsMarkAs = ref([
return undefined return undefined
} }
myReceiver.read = false; myReceiver.read = false
return store.dispatch("messagereluser/update", myReceiver); return store.dispatch("messagereluser/update", myReceiver)
}) })
Promise.all(promises) Promise.all(promises)
.then(() => messageRelUserStore.findUnreadCount()) .then(() => messageRelUserStore.findUnreadCount())
.catch((e) => notification.showErrorNotification(e)) .catch((e) => notification.showErrorNotification(e))
.finally(() => selectedItems.value = []) .finally(() => (selectedItems.value = []))
}, },
}, },
]); ])
const mMessageList = ref(null); const mMessageList = ref(null)
const mToggleMessagesList = (event) => mMessageList.value.toggle(event); const mToggleMessagesList = (event) => mMessageList.value.toggle(event)
const dtMessages = ref(null); const dtMessages = ref(null)
const initialRowsPerPage = 10; const initialRowsPerPage = 10
const goToCompose = () => { const goToCompose = () => {
router.push({ router.push({
name: "MessageCreate", name: "MessageCreate",
query: route.query, query: route.query,
}); })
}; }
const { result: messageTagsResult } = useQuery( const { result: messageTagsResult } = useQuery(
GET_USER_MESSAGE_TAGS, GET_USER_MESSAGE_TAGS,
{ user: user.value["@id"] }, { user: user.value["@id"] },
{ fetchPolicy: "cache-and-network" } { fetchPolicy: "cache-and-network" },
); )
const tags = computed(() => messageTagsResult.value?.messageTags?.edges.map(({ node }) => node) ?? []); const tags = computed(() => messageTagsResult.value?.messageTags?.edges.map(({ node }) => node) ?? [])
const items = computed(() => store.getters["message/getRecents"]); const items = computed(() => store.getters["message/getRecents"])
const isLoading = computed(() => store.getters["message/isLoading"]); const isLoading = computed(() => store.getters["message/isLoading"])
const totalItems = computed(() => store.getters["message/getTotalItems"]); const totalItems = computed(() => store.getters["message/getTotalItems"])
const title = ref(null); const title = ref(null)
const selectedItems = ref([]); const selectedItems = ref([])
const rowClass = (data) => { const rowClass = (data) => {
const myReceiver = findMyReceiver(data); const myReceiver = findMyReceiver(data)
if (!myReceiver) { if (!myReceiver) {
return []; return []
} }
return [{ "font-semibold": !myReceiver.read }]; return [{ "font-semibold": !myReceiver.read }]
}; }
let fetchPayload = { let fetchPayload = {
"order[sendDate]": "desc", "order[sendDate]": "desc",
itemsPerPage: initialRowsPerPage, itemsPerPage: initialRowsPerPage,
page: 1, page: 1,
}; }
function loadMessages(reset = true) { function loadMessages(reset = true) {
if (reset) { if (reset) {
store.dispatch("message/resetList"); store.dispatch("message/resetList")
dtMessages.value.resetPage(); dtMessages.value.resetPage()
} }
store.dispatch("message/fetchAll", fetchPayload); store.dispatch("message/fetchAll", fetchPayload)
} }
function showInbox() { function showInbox() {
title.value = t("Inbox"); title.value = t("Inbox")
fetchPayload = { fetchPayload = {
msgType: MESSAGE_TYPE_INBOX, msgType: MESSAGE_TYPE_INBOX,
@ -242,13 +285,13 @@ function showInbox() {
"order[sendDate]": "desc", "order[sendDate]": "desc",
itemsPerPage: initialRowsPerPage, itemsPerPage: initialRowsPerPage,
page: 1, page: 1,
}; }
loadMessages(); loadMessages()
} }
function showInboxByTag(tag) { function showInboxByTag(tag) {
title.value = tag.tag; title.value = tag.tag
fetchPayload = { fetchPayload = {
msgType: MESSAGE_TYPE_INBOX, msgType: MESSAGE_TYPE_INBOX,
@ -257,13 +300,13 @@ function showInboxByTag(tag) {
"order[sendDate]": "desc", "order[sendDate]": "desc",
itemsPerPage: initialRowsPerPage, itemsPerPage: initialRowsPerPage,
page: 1, page: 1,
}; }
loadMessages(); loadMessages()
} }
function showUnread() { function showUnread() {
title.value = t("Unread"); title.value = t("Unread")
fetchPayload = { fetchPayload = {
msgType: MESSAGE_TYPE_INBOX, msgType: MESSAGE_TYPE_INBOX,
@ -272,13 +315,13 @@ function showUnread() {
"receivers.read": false, "receivers.read": false,
itemsPerPage: initialRowsPerPage, itemsPerPage: initialRowsPerPage,
page: 1, page: 1,
}; }
loadMessages(); loadMessages()
} }
function showSent() { function showSent() {
title.value = t("Sent"); title.value = t("Sent")
fetchPayload = { fetchPayload = {
msgType: MESSAGE_TYPE_INBOX, msgType: MESSAGE_TYPE_INBOX,
@ -286,23 +329,23 @@ function showSent() {
"order[sendDate]": "desc", "order[sendDate]": "desc",
itemsPerPage: initialRowsPerPage, itemsPerPage: initialRowsPerPage,
page: 1, page: 1,
}; }
loadMessages(); loadMessages()
} }
function refreshMessages() { function refreshMessages() {
fetchPayload.itemsPerPage = initialRowsPerPage; fetchPayload.itemsPerPage = initialRowsPerPage
fetchPayload.page = 1; fetchPayload.page = 1
loadMessages(); loadMessages()
} }
function onPage(event) { function onPage(event) {
fetchPayload.page = event.page + 1; fetchPayload.page = event.page + 1
fetchPayload.itemsPerPage = event.rows; fetchPayload.itemsPerPage = event.rows
loadMessages(false); loadMessages(false)
} }
function onRowClick({ data }) { function onRowClick({ data }) {
@ -311,25 +354,25 @@ function onRowClick({ data }) {
query: { query: {
id: data["@id"], id: data["@id"],
}, },
}); })
} }
function findMyReceiver(message) { function findMyReceiver(message) {
const receivers = [...message.receiversTo, ...message.receiversCc]; const receivers = [...message.receiversTo, ...message.receiversCc]
return receivers.find(({ receiver }) => receiver["@id"] === user.value["@id"]); return receivers.find(({ receiver }) => receiver["@id"] === user.value["@id"])
} }
async function deleteMessage(message) { async function deleteMessage(message) {
if (message.sender["@id"] === user.value["@id"]) { if (message.sender["@id"] === user.value["@id"]) {
message.status = MESSAGE_STATUS_DELETED; message.status = MESSAGE_STATUS_DELETED
await store.dispatch("message/update", message); await store.dispatch("message/update", message)
} else { } else {
const myReceiver = findMyReceiver(message); const myReceiver = findMyReceiver(message)
if (myReceiver) { if (myReceiver) {
await store.dispatch("messagereluser/del", myReceiver); await store.dispatch("messagereluser/del", myReceiver)
} }
} }
} }
@ -339,13 +382,13 @@ function showDlgConfirmDeleteSingle({ data }) {
header: t("Confirmation"), header: t("Confirmation"),
message: t(`Are you sure you want to delete "${data.title}"?`), message: t(`Are you sure you want to delete "${data.title}"?`),
accept: async () => { accept: async () => {
await deleteMessage(data); await deleteMessage(data)
loadMessages(); loadMessages()
notification.showSuccessNotification(t("Message deleted")); notification.showSuccessNotification(t("Message deleted"))
}, },
}); })
} }
function showDlgConfirmDeleteMultiple() { function showDlgConfirmDeleteMultiple() {
@ -354,19 +397,19 @@ function showDlgConfirmDeleteMultiple() {
message: t("Are you sure you want to delete the selected items?"), message: t("Are you sure you want to delete the selected items?"),
accept: async () => { accept: async () => {
for (const message of selectedItems.value) { for (const message of selectedItems.value) {
await deleteMessage(message); await deleteMessage(message)
} }
loadMessages(); loadMessages()
notification.showSuccessNotification(t("Messages deleted")); notification.showSuccessNotification(t("Messages deleted"))
selectedItems.value = []; selectedItems.value = []
}, },
}); })
} }
onMounted(() => { onMounted(() => {
showInbox(); showInbox()
}); })
</script> </script>

@ -1,15 +1,40 @@
<template> <template>
<div v-if="item"> <div v-if="item">
<div class="flex gap-4 items-center"> <div class="flex gap-4 items-center">
<h2 class="mr-auto" v-text="item.title" /> <h2
class="mr-auto"
v-text="item.title"
/>
<BaseButton :disabled="isLoading" icon="reply" only-icon type="black" @click="reply" /> <BaseButton
:disabled="isLoading"
icon="reply"
only-icon
type="black"
@click="reply"
/>
<BaseButton :disabled="isLoading" icon="reply-all" only-icon type="black" @click="replyAll" /> <BaseButton
:disabled="isLoading"
icon="reply-all"
only-icon
type="black"
@click="replyAll"
/>
<BaseButton icon="calendar-plus" only-icon type="black" @click="createEvent" /> <BaseButton
icon="calendar-plus"
only-icon
type="black"
@click="createEvent"
/>
<BaseButton icon="delete" only-icon type="black" @click="confirmDelete" /> <BaseButton
icon="delete"
only-icon
type="black"
@click="confirmDelete"
/>
</div> </div>
<hr /> <hr />
@ -40,7 +65,11 @@
<div> <div>
{{ t("From") }} {{ t("From") }}
<BaseChip :value="item.sender" image-field="illustrationUrl" label-field="username" /> <BaseChip
:value="item.sender"
image-field="illustrationUrl"
label-field="username"
/>
</div> </div>
<div> <div>
@ -78,14 +107,23 @@
<p class="my-3">{{ item.attachments.length }} {{ $t("Attachments") }}</p> <p class="my-3">{{ item.attachments.length }} {{ $t("Attachments") }}</p>
<div class="q-gutter-y-sm q-gutter-x-sm row"> <div class="q-gutter-y-sm q-gutter-x-sm row">
<div v-for="(attachment, index) in item.attachments" :key="index"> <div
v-for="(attachment, index) in item.attachments"
:key="index"
>
<div v-if="attachment.resourceNode.resourceFile.audio"> <div v-if="attachment.resourceNode.resourceFile.audio">
<audio controls> <audio controls>
<source :src="attachment.downloadUrl" /> <source :src="attachment.downloadUrl" />
</audio> </audio>
</div> </div>
<q-btn v-else :href="attachment.downloadUrl" flat icon="attachment" type="a"> <q-btn
v-else
:href="attachment.downloadUrl"
flat
icon="attachment"
type="a"
>
{{ attachment.resourceNode.resourceFile.originalName }} {{ attachment.resourceNode.resourceFile.originalName }}
</q-btn> </q-btn>
</div> </div>
@ -97,114 +135,116 @@
</template> </template>
<script setup> <script setup>
import { useStore } from "vuex"; import { useStore } from "vuex"
import Loading from "../../components/Loading.vue"; import Loading from "../../components/Loading.vue"
import { computed, ref } from "vue"; import { computed, ref } from "vue"
import isEmpty from "lodash/isEmpty"; import isEmpty from "lodash/isEmpty"
import axios from "axios"; import axios from "axios"
import { ENTRYPOINT } from "../../config/entrypoint"; import { ENTRYPOINT } from "../../config/entrypoint"
import { useRoute, useRouter } from "vue-router"; import { useRoute, useRouter } from "vue-router"
import BaseButton from "../../components/basecomponents/BaseButton.vue"; import BaseButton from "../../components/basecomponents/BaseButton.vue"
import { useConfirm } from "primevue/useconfirm"; import { useConfirm } from "primevue/useconfirm"
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n"
import BaseChip from "../../components/basecomponents/BaseChip.vue"; import BaseChip from "../../components/basecomponents/BaseChip.vue"
import BaseAutocomplete from "../../components/basecomponents/BaseAutocomplete.vue"; import BaseAutocomplete from "../../components/basecomponents/BaseAutocomplete.vue"
import { useRelativeDatetime } from "../../composables/formatDate"; import { useRelativeDatetime } from "../../composables/formatDate"
import { useMessageRelUserStore } from "../../store/messageRelUserStore" import { useMessageRelUserStore } from "../../store/messageRelUserStore"
const confirm = useConfirm(); const confirm = useConfirm()
const { t } = useI18n(); const { t } = useI18n()
const isLoadingSelect = ref(false); const isLoadingSelect = ref(false)
const store = useStore(); const store = useStore()
const user = store.getters["security/getUser"]; const user = store.getters["security/getUser"]
//const find = store.getters["message/find"]; //const find = store.getters["message/find"];
const route = useRoute(); const route = useRoute()
const router = useRouter(); const router = useRouter()
const messageRelUserStore = useMessageRelUserStore() const messageRelUserStore = useMessageRelUserStore()
let id = route.params.id; let id = route.params.id
if (isEmpty(id)) { if (isEmpty(id)) {
id = route.query.id; id = route.query.id
} }
const isLoading = computed(() => store.state.message.isLoading); const isLoading = computed(() => store.state.message.isLoading)
const item = ref(null); const item = ref(null)
const myReceiver = ref(null); const myReceiver = ref(null)
store.dispatch("message/load", id).then((responseItem) => { store.dispatch("message/load", id).then((responseItem) => {
item.value = responseItem; item.value = responseItem
myReceiver.value = [...responseItem.receiversTo, ...responseItem.receiversCc].find( myReceiver.value = [...responseItem.receiversTo, ...responseItem.receiversCc].find(
({ receiver }) => receiver["@id"] === user["@id"] ({ receiver }) => receiver["@id"] === user["@id"],
); )
// Change to read. // Change to read.
if (myReceiver.value && false === myReceiver.value.read) { if (myReceiver.value && false === myReceiver.value.read) {
store.dispatch("messagereluser/update", { store
.dispatch("messagereluser/update", {
"@id": myReceiver.value["@id"], "@id": myReceiver.value["@id"],
read: true, read: true,
}).then(() => messageRelUserStore.findUnreadCount()); })
.then(() => messageRelUserStore.findUnreadCount())
} }
}); })
function confirmDelete() { function confirmDelete() {
confirm.require({ confirm.require({
header: t("Confirmation"), header: t("Confirmation"),
message: t(`Are you sure you want to delete "${item.value.title}"?`), message: t(`Are you sure you want to delete "${item.value.title}"?`),
accept: async () => { accept: async () => {
await store.dispatch("message/del", item); await store.dispatch("message/del", item)
await router.push({ await router.push({
name: "MessageList", name: "MessageList",
}); })
}, },
}); })
} }
function getTagIndex(tag) { function getTagIndex(tag) {
return myReceiver.value.tags.findIndex((receiverTag) => receiverTag["@id"] === tag["@id"]); return myReceiver.value.tags.findIndex((receiverTag) => receiverTag["@id"] === tag["@id"])
} }
function mapTagsToIds() { function mapTagsToIds() {
return myReceiver.value.tags.map((receiverTag) => receiverTag["@id"]); return myReceiver.value.tags.map((receiverTag) => receiverTag["@id"])
} }
async function onRemoveTagFromMessage(tag) { async function onRemoveTagFromMessage(tag) {
const index = getTagIndex(tag); const index = getTagIndex(tag)
if (index < 0) { if (index < 0) {
return; return
} }
myReceiver.value.tags.splice(index, 1); myReceiver.value.tags.splice(index, 1)
const newTagIds = mapTagsToIds(); const newTagIds = mapTagsToIds()
await store.dispatch("messagereluser/update", { await store.dispatch("messagereluser/update", {
"@id": myReceiver.value["@id"], "@id": myReceiver.value["@id"],
tags: newTagIds, tags: newTagIds,
}); })
} }
function reply() { function reply() {
router.push({ name: "MessageReply", query: { ...route.query } }); router.push({ name: "MessageReply", query: { ...route.query } })
} }
function replyAll() { function replyAll() {
router.push({ name: `MessageReply`, query: { ...route.query, all: 1 } }); router.push({ name: `MessageReply`, query: { ...route.query, all: 1 } })
} }
function createEvent() { function createEvent() {
let params = route.query; let params = route.query
router.push({ name: "CCalendarEventCreate", query: params }); router.push({ name: "CCalendarEventCreate", query: params })
} }
const foundTag = ref(""); const foundTag = ref("")
function onSearchTags(query) { function onSearchTags(query) {
isLoadingSelect.value = true; isLoadingSelect.value = true
return axios return axios
.get(ENTRYPOINT + "message_tags", { .get(ENTRYPOINT + "message_tags", {
@ -214,14 +254,14 @@ function onSearchTags(query) {
}, },
}) })
.then((response) => { .then((response) => {
isLoadingSelect.value = false; isLoadingSelect.value = false
return response.data["hydra:member"]; return response.data["hydra:member"]
}) })
.catch(function (error) { .catch(function (error) {
isLoadingSelect.value = false; isLoadingSelect.value = false
console.log(error); console.log(error)
}); })
} }
async function onItemSelect({ value }) { async function onItemSelect({ value }) {
@ -232,29 +272,29 @@ async function onItemSelect({ value }) {
await store.dispatch("messagetag/create", { await store.dispatch("messagetag/create", {
user: user["@id"], user: user["@id"],
tag: value.tag, tag: value.tag,
}); })
} catch (e) { } catch (e) {
return return
} }
} else { } else {
const existingIndex = getTagIndex(value["@id"]) >= 0; const existingIndex = getTagIndex(value["@id"]) >= 0
if (existingIndex) { if (existingIndex) {
return; return
} }
} }
foundTag.value = ""; foundTag.value = ""
if (myReceiver.value && newTag.value) { if (myReceiver.value && newTag.value) {
myReceiver.value.tags.push(newTag.value); myReceiver.value.tags.push(newTag.value)
const newTagIds = mapTagsToIds(); const newTagIds = mapTagsToIds()
await store.dispatch("messagereluser/update", { await store.dispatch("messagereluser/update", {
"@id": myReceiver.value["@id"], "@id": myReceiver.value["@id"],
tags: newTagIds, tags: newTagIds,
}); })
} }
} }
</script> </script>
Loading…
Cancel
Save