232201_test_to_master #62

Merged
alexm merged 50 commits from 232201_test_to_master into master 2023-06-01 07:26:39 +00:00
3 changed files with 173 additions and 248 deletions
Showing only changes of commit ba9d8b3c21 - Show all commits

View File

@ -398,8 +398,8 @@ export default {
notificationsManager: { notificationsManager: {
activeNotifications: 'Notificaciones activas', activeNotifications: 'Notificaciones activas',
availableNotifications: 'Notificaciones disponibles', availableNotifications: 'Notificaciones disponibles',
subscribed: 'Te has suscrito a la notificación', subscribed: 'Se ha suscrito a la notificación',
unsubscribed: 'Te has dado de baja de la notificación', unsubscribed: 'Se ha dado de baja de la notificación',
}, },
imageNotFound: 'No se ha encontrado la imagen', imageNotFound: 'No se ha encontrado la imagen',
}, },

View File

@ -1,10 +1,9 @@
<script setup> <script setup>
import { onMounted, computed, ref, onUpdated } from 'vue';
import { useRoute } from 'vue-router';
import { useI18n } from 'vue-i18n';
import { useQuasar } from 'quasar';
import { useSession } from 'src/composables/useSession';
import axios from 'axios'; import axios from 'axios';
import { useQuasar } from 'quasar';
import { computed, onMounted, onUpdated, ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { useRoute } from 'vue-router';
const $props = defineProps({ const $props = defineProps({
id: { id: {
@ -13,276 +12,200 @@ const $props = defineProps({
default: null, default: null,
}, },
}); });
const entityId = computed(() => $props.id || route.params.id);
onMounted(async () => await fetch()); onMounted(() => fetch());
onUpdated(async () => await fetch()); onUpdated(() => fetch());
const route = useRoute(); const route = useRoute();
const { t } = useI18n(); const { t } = useI18n();
const { getToken } = useSession();
const quasar = useQuasar(); const quasar = useQuasar();
const entityId = computed(() => { const notifications = ref([]);
return $props.id || route.params.id;
});
const worker = ref();
const workerFilter = {
include: [
{
relation: 'user',
scope: {
fields: ['email', 'name', 'nickname', 'roleFk'],
},
},
{
relation: 'department',
scope: {
include: [
{
relation: 'department',
},
],
},
},
],
};
const notificationAcls = ref([]);
const isLoading = ref(false);
async function fetch() { async function fetch() {
isLoading.value = true;
const { data } = await axios.get(`Workers/${entityId.value}`, {
params: {
filter: JSON.stringify(workerFilter),
},
headers: {
Authorization: getToken(),
},
});
try { try {
const filter = { await axios
where: { .get(`NotificationSubscriptions`, {
userFk: entityId.value, params: {
}, filter: {
include: [
{
relation: 'notification',
},
],
};
const subscribedNotifs = await axios.get(`NotificationSubscriptions`, {
params: {
filter: JSON.stringify(filter),
},
headers: {
Authorization: getToken(),
},
});
data.subscribedNotifs = subscribedNotifs.data;
const filterAcl = {
include: [
{
relation: 'notification',
scope: {
include: [ include: [
{ {
relation: 'subscription', relation: 'notification',
}, },
], ],
where: {
userFk: entityId.value,
},
}, },
}, },
{ })
relation: 'role', .then(async (res) => {
}, if (res.data) {
], res.data.forEach((subscription) => {
}; notifications.value.push({
id: subscription.id,
const notifsAcl = await axios.get(`NotificationAcls`, { notificationFk: subscription.notificationFk,
params: { name: subscription.notification.name,
filter: JSON.stringify(filterAcl), description: subscription.notification.description,
}, active: true,
headers: { });
Authorization: getToken(), });
},
});
let notifications = [];
notifsAcl.data.forEach((acl) => {
let notification = {
id: acl.notification.id,
name: acl.notification.name,
description: acl.notification.description,
active: false,
allowed: false,
};
if (acl.roleFk == data.user.roleFk) {
notification.allowed = true;
} else {
notification.allowed = false;
}
if (data.subscribedNotifs.length > 0) {
data.subscribedNotifs.forEach((sub) => {
if (sub.notificationFk == acl.notification.id) {
if (notification.allowed) {
notification.active = true;
}
}
});
}
let found = false;
notifications.forEach((notif) => {
if (notif.id == notification.id) {
found = true;
} }
}); });
await axios
if (!found) { .get(`RoleMappings`, {
if (!notification.allowed) { params: {
notification.active = null; filter: {
fields: ['roleId'],
where: {
principalId: entityId.value,
},
},
},
})
.then(async (res) => {
if (res.data) {
await axios
.get(`NotificationAcls`, {
params: {
filter: {
include: [
{
relation: 'notification',
},
],
where: {
roleFk: {
inq: res.data.map((role) => {
return role.roleId;
}),
},
},
},
},
})
.then(async (res) => {
if (res.data) {
res.data.forEach((acl) => {
const activeNotif = notifications.value.find(
(notif) =>
notif.notificationFk === acl.notificationFk
);
if (!activeNotif) {
notifications.value.push({
id: null,
notificationFk: acl.notificationFk,
name: acl.notification.name,
description: acl.notification.description,
active: false,
});
}
});
}
});
} }
notifications.push(notification); });
} else {
notifications.forEach((notif) => {
if (notif.id == notification.id) {
if (notification.allowed && !notif.allowed) {
notif.allowed = true;
notif.active = notification.active;
}
}
});
}
});
notificationAcls.value = notifications;
sortNotifs();
} catch (e) { } catch (e) {
console.log(e); //
} }
worker.value = data;
isLoading.value = false;
} }
function sortNotifs() { async function disableNotification(notification) {
notificationAcls.value.sort((a, b) => { await axios.delete(`NotificationSubscriptions/${notification.id}`).then(() => {
if (a.allowed && !b.allowed) { notification.id = null;
return -1; notification.active = false;
} else if (!a.allowed && b.allowed) {
return 1;
} else {
if (a.active && !b.active) {
return 1;
} else if (!a.active && b.active) {
return -1;
} else {
return 0;
}
}
});
}
async function toggleNotif(notif, chip) {
if (chip) {
notif.active = !notif.active;
}
if (notif.active) {
await axios.post(
`NotificationSubscriptions`,
{
notificationFk: notif.id,
userFk: entityId.value,
},
{
headers: {
Authorization: getToken(),
},
}
);
quasar.notify({
type: 'positive',
message: t('worker.notificationsManager.subscribed'),
});
} else {
await axios.post(
`NotificationSubscriptions/deleteNotification`,
{
notificationId: this.worker.subscribedNotifs.find((sub) => sub.notificationFk == notif.id).id,
},
{
headers: {
Authorization: getToken(),
},
}
);
quasar.notify({ quasar.notify({
type: 'positive', type: 'positive',
message: t('worker.notificationsManager.unsubscribed'), message: t('worker.notificationsManager.unsubscribed'),
}); });
});
}
async function toggleNotification(notification) {
if (!notification.active) {
await disableNotification(notification);
} else {
await axios
.post(`NotificationSubscriptions`, {
notificationFk: notification.notificationFk,
userFk: entityId.value,
})
.catch(() => (notification.active = false))
.then((res) => {
if (res.data) {
notification.id = res.data.id;
quasar.notify({
type: 'positive',
message: t('worker.notificationsManager.subscribed'),
});
}
});
} }
await fetch();
} }
</script> </script>
<template> <template>
<q-card> <QPage>
<skeleton-summary v-if="!worker" /> <QCard class="q-pa-md">
<template v-if="worker"> <QList>
<div class="header bg-primary q-pa-sm">{{ worker.id }} - {{ worker.firstName }}</div> <div
<q-list> v-show="
<q-item-label header class="text-h6"> notifications.filter(
{{ t('worker.notificationsManager.activeNotifications') }} (notification) => notification.active == true
</q-item-label> ).length > 0
<q-item> "
<div v-for="notif in notificationAcls" :key="notif.id"> >
<q-chip <QItemLabel header class="text-h6">
v-if="notif.active" {{ t('worker.notificationsManager.activeNotifications') }}
:key="notif.id" </QItemLabel>
:label="notif.name" <QItem>
text-color="white" <div
color="primary" v-for="notification in notifications.filter(
class="q-mr-sm" (notification) => notification.active == true
removable )"
@remove="toggleNotif(notif, true)" :key="notification.id"
/> >
</div> <QChip
</q-item> :key="notification.id"
<q-item-label header class="text-h6"> :label="notification.name"
{{ t('worker.notificationsManager.availableNotifications') }} text-color="white"
</q-item-label> color="primary"
class="q-mr-sm"
<div class="row"> removable
<q-item @remove="disableNotification(notification)"
class="col"
:key="notif.id"
v-for="notif in notificationAcls"
style="min-width: 350px; max-width: 350px"
>
<q-item-section>
<q-item-label>{{ notif.name }}</q-item-label>
<q-item-label caption>{{ notif.description }}</q-item-label>
</q-item-section>
<q-item-section side top>
<q-toggle
:disable="!notif.allowed || isLoading"
checked-icon="check"
unchecked-icon="close"
indeterminate-icon="block"
v-model="notif.active"
@update:model-value="toggleNotif(notif)"
/> />
</q-item-section> </div>
</q-item> </QItem>
</div> </div>
</q-list> <div v-show="notifications.length > 0">
</template> <QItemLabel header class="text-h6">
</q-card> {{ t('worker.notificationsManager.availableNotifications') }}
</QItemLabel>
<div class="row">
<QItem
class="col-3"
:key="notification.notificationFk"
v-for="notification in notifications"
>
<QItemSection>
<QItemLabel>{{ notification.name }}</QItemLabel>
<QItemLabel caption>{{
notification.description
}}</QItemLabel>
</QItemSection>
<QItemSection side top>
<QToggle
checked-icon="check"
unchecked-icon="close"
indeterminate-icon="block"
v-model="notification.active"
@update:model-value="toggleNotification(notification)"
/>
</QItemSection>
</QItem>
</div>
</div>
</QList>
</QCard>
</QPage>
</template> </template>

View File

@ -11,7 +11,7 @@ export default {
redirect: { name: 'WorkerMain' }, redirect: { name: 'WorkerMain' },
menus: { menus: {
main: ['WorkerList'], main: ['WorkerList'],
card: [], card: ['WorkerNotificationsManager'],
}, },
children: [ children: [
{ {
@ -42,6 +42,7 @@ export default {
path: 'summary', path: 'summary',
meta: { meta: {
title: 'summary', title: 'summary',
icon: 'launch',
}, },
component: () => import('src/pages/Worker/Card/WorkerSummary.vue'), component: () => import('src/pages/Worker/Card/WorkerSummary.vue'),
}, },
@ -50,6 +51,7 @@ export default {
path: 'notifications', path: 'notifications',
meta: { meta: {
title: 'notifications', title: 'notifications',
icon: 'notifications',
}, },
component: () => import('src/pages/Worker/Card/WorkerNotificationsManager.vue'), component: () => import('src/pages/Worker/Card/WorkerNotificationsManager.vue'),
}, },