Merge pull request 'fixes #4797 Seccion Worker/Notification' (!51) from 4797-worker-notification-selector into dev
gitea/salix-front/pipeline/head This commit looks good
Details
gitea/salix-front/pipeline/head This commit looks good
Details
Reviewed-on: #51 Reviewed-by: Alex Moreno <alexm@verdnatura.es>
This commit is contained in:
commit
a1ca8c822f
|
@ -361,6 +361,7 @@ export default {
|
||||||
list: 'List',
|
list: 'List',
|
||||||
basicData: 'Basic data',
|
basicData: 'Basic data',
|
||||||
summary: 'Summary',
|
summary: 'Summary',
|
||||||
|
notifications: 'Notifications',
|
||||||
},
|
},
|
||||||
list: {
|
list: {
|
||||||
name: 'Name',
|
name: 'Name',
|
||||||
|
@ -394,6 +395,12 @@ export default {
|
||||||
role: 'Role',
|
role: 'Role',
|
||||||
sipExtension: 'Extension',
|
sipExtension: 'Extension',
|
||||||
},
|
},
|
||||||
|
notificationsManager: {
|
||||||
|
activeNotifications: 'Active notifications',
|
||||||
|
availableNotifications: 'Available notifications',
|
||||||
|
subscribed: 'Subscribed to the notification',
|
||||||
|
unsubscribed: 'Unsubscribed from the notification',
|
||||||
|
},
|
||||||
imageNotFound: 'Image not found',
|
imageNotFound: 'Image not found',
|
||||||
},
|
},
|
||||||
wagon: {
|
wagon: {
|
||||||
|
|
|
@ -361,6 +361,7 @@ export default {
|
||||||
list: 'Listado',
|
list: 'Listado',
|
||||||
basicData: 'Datos básicos',
|
basicData: 'Datos básicos',
|
||||||
summary: 'Resumen',
|
summary: 'Resumen',
|
||||||
|
notifications: 'Notificaciones',
|
||||||
},
|
},
|
||||||
list: {
|
list: {
|
||||||
name: 'Nombre',
|
name: 'Nombre',
|
||||||
|
@ -394,6 +395,12 @@ export default {
|
||||||
role: 'Rol',
|
role: 'Rol',
|
||||||
sipExtension: 'Extensión',
|
sipExtension: 'Extensión',
|
||||||
},
|
},
|
||||||
|
notificationsManager: {
|
||||||
|
activeNotifications: 'Notificaciones activas',
|
||||||
|
availableNotifications: 'Notificaciones disponibles',
|
||||||
|
subscribed: 'Se ha suscrito a 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',
|
||||||
},
|
},
|
||||||
wagon: {
|
wagon: {
|
||||||
|
|
|
@ -0,0 +1,142 @@
|
||||||
|
<script setup>
|
||||||
|
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({
|
||||||
|
id: {
|
||||||
|
type: Number,
|
||||||
|
required: false,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const entityId = computed(() => $props.id || route.params.id);
|
||||||
|
|
||||||
|
onMounted(() => fetch());
|
||||||
|
onUpdated(() => fetch());
|
||||||
|
|
||||||
|
const route = useRoute();
|
||||||
|
const { t } = useI18n();
|
||||||
|
const quasar = useQuasar();
|
||||||
|
|
||||||
|
const notifications = ref([]);
|
||||||
|
|
||||||
|
async function fetch() {
|
||||||
|
try {
|
||||||
|
await axios
|
||||||
|
.get(`NotificationSubscriptions/${entityId.value}/getList`)
|
||||||
|
.then(async (res) => {
|
||||||
|
if (res.data) {
|
||||||
|
notifications.value = res.data;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function disableNotification(notification) {
|
||||||
|
await axios
|
||||||
|
.delete(`NotificationSubscriptions/${notification.id}`)
|
||||||
|
.catch(() => (notification.active = true))
|
||||||
|
.then((res) => {
|
||||||
|
if (res.data) {
|
||||||
|
notification.id = null;
|
||||||
|
notification.active = false;
|
||||||
|
quasar.notify({
|
||||||
|
type: 'positive',
|
||||||
|
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'),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<QPage>
|
||||||
|
<QCard class="q-pa-md">
|
||||||
|
<QList>
|
||||||
|
<div
|
||||||
|
v-show="
|
||||||
|
notifications.filter(
|
||||||
|
(notification) => notification.active == true
|
||||||
|
).length
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<QItemLabel header class="text-h6">
|
||||||
|
{{ t('worker.notificationsManager.activeNotifications') }}
|
||||||
|
</QItemLabel>
|
||||||
|
<QItem>
|
||||||
|
<div
|
||||||
|
v-for="notification in notifications.filter(
|
||||||
|
(notification) => notification.active == true
|
||||||
|
)"
|
||||||
|
:key="notification.id"
|
||||||
|
>
|
||||||
|
<QChip
|
||||||
|
:key="notification.id"
|
||||||
|
:label="notification.name"
|
||||||
|
text-color="white"
|
||||||
|
color="primary"
|
||||||
|
class="q-mr-sm"
|
||||||
|
removable
|
||||||
|
@remove="disableNotification(notification)"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</QItem>
|
||||||
|
</div>
|
||||||
|
<div v-show="notifications.length">
|
||||||
|
<QItemLabel header class="text-h6">
|
||||||
|
{{ 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>
|
|
@ -11,7 +11,7 @@ export default {
|
||||||
redirect: { name: 'WorkerMain' },
|
redirect: { name: 'WorkerMain' },
|
||||||
menus: {
|
menus: {
|
||||||
main: ['WorkerList'],
|
main: ['WorkerList'],
|
||||||
card: [],
|
card: ['WorkerNotificationsManager'],
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
|
@ -42,9 +42,19 @@ 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'),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'WorkerNotificationsManager',
|
||||||
|
path: 'notifications',
|
||||||
|
meta: {
|
||||||
|
title: 'notifications',
|
||||||
|
icon: 'notifications',
|
||||||
|
},
|
||||||
|
component: () => import('src/pages/Worker/Card/WorkerNotificationsManager.vue'),
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
describe('WorkerNotificationsManager', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
const workerId = 1110;
|
||||||
|
cy.viewport(1280, 720);
|
||||||
|
cy.login('salesBoss');
|
||||||
|
cy.visit(`/#/worker/${workerId}/notifications`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should unsubscribe 2 notifications, check the unsubscription has been saved, subscribe to other one and should check the data has been saved', () => {
|
||||||
|
cy.get('.q-chip').should('have.length', 3);
|
||||||
|
cy.get('.q-toggle__thumb').eq(0).click();
|
||||||
|
cy.get('.q-notification__message').should('have.text', 'Unsubscribed from the notification');
|
||||||
|
cy.get('.q-chip > .q-icon').eq(0).click();
|
||||||
|
|
||||||
|
cy.reload();
|
||||||
|
|
||||||
|
cy.get('.q-chip').should('have.length', 1);
|
||||||
|
cy.get('.q-toggle__thumb').should('have.length', 3).eq(0).click();
|
||||||
|
cy.get('.q-notification__message').should('have.text', 'Subscribed to the notification');
|
||||||
|
cy.get('.q-toggle__thumb').should('have.length', 3).eq(1).click();
|
||||||
|
cy.get('.q-notification__message').should('have.text', 'Subscribed to the notification');
|
||||||
|
|
||||||
|
cy.reload();
|
||||||
|
|
||||||
|
cy.get('.q-chip').should('have.length', 3);
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,100 @@
|
||||||
|
import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest';
|
||||||
|
import { createWrapper, axios } from 'app/test/vitest/helper';
|
||||||
|
import WorkerNotificationsManager from 'src/pages/Worker/Card/WorkerNotificationsManager.vue';
|
||||||
|
|
||||||
|
describe('WorkerNotificationsManager', () => {
|
||||||
|
let vm;
|
||||||
|
const entityId = 1110;
|
||||||
|
|
||||||
|
beforeAll(() => {
|
||||||
|
vm = createWrapper(WorkerNotificationsManager, {
|
||||||
|
propsData: {
|
||||||
|
id: entityId,
|
||||||
|
},
|
||||||
|
}).vm;
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
vi.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('fetch()', () => {
|
||||||
|
it('should fetch notification subscriptions and role mappings', async () => {
|
||||||
|
vi.spyOn(axios, 'get')
|
||||||
|
.mockResolvedValueOnce({
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
name: 'Name 1',
|
||||||
|
description: 'Description 1',
|
||||||
|
notificationFk: 1,
|
||||||
|
active: true
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
await vm.fetch();
|
||||||
|
|
||||||
|
expect(axios.get).toHaveBeenCalledWith(`NotificationSubscriptions/${entityId}/getList`);
|
||||||
|
expect(vm.notifications).toEqual([
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
notificationFk: 1,
|
||||||
|
name: 'Name 1',
|
||||||
|
description: 'Description 1',
|
||||||
|
active: true,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('disableNotification()', () => {
|
||||||
|
it('should disable the notification', async () => {
|
||||||
|
vi.spyOn(axios, 'delete').mockResolvedValue({ data: { count: 1 } });
|
||||||
|
vi.spyOn(vm.quasar, 'notify');
|
||||||
|
const subscriptionId = 1;
|
||||||
|
vm.notifications = [{ id: 1, active: true }];
|
||||||
|
|
||||||
|
await vm.disableNotification(vm.notifications[0]);
|
||||||
|
|
||||||
|
expect(axios.delete).toHaveBeenCalledWith(
|
||||||
|
`NotificationSubscriptions/${subscriptionId}`
|
||||||
|
);
|
||||||
|
expect(vm.notifications[0].id).toBeNull();
|
||||||
|
expect(vm.notifications[0].id).toBeFalsy();
|
||||||
|
expect(vm.quasar.notify).toHaveBeenCalledWith(
|
||||||
|
expect.objectContaining({ type: 'positive' })
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('toggleNotification()', () => {
|
||||||
|
it('should activate the notification', async () => {
|
||||||
|
vi.spyOn(axios, 'post').mockResolvedValue({
|
||||||
|
data: { id: 1, notificationFk: 1 },
|
||||||
|
});
|
||||||
|
vm.notifications = [{ id: null, active: true, notificationFk: 1 }];
|
||||||
|
|
||||||
|
await vm.toggleNotification(vm.notifications[0]);
|
||||||
|
|
||||||
|
expect(axios.post).toHaveBeenCalledWith('NotificationSubscriptions', {
|
||||||
|
notificationFk: 1,
|
||||||
|
userFk: entityId,
|
||||||
|
});
|
||||||
|
expect(vm.notifications[0].id).toBe(1);
|
||||||
|
expect(vm.notifications[0].active).toBeTruthy();
|
||||||
|
expect(vm.quasar.notify).toHaveBeenCalledWith(
|
||||||
|
expect.objectContaining({ type: 'positive' })
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should disable the notification', async () => {
|
||||||
|
vi.spyOn(vm, 'disableNotification');
|
||||||
|
vm.notifications = [{ id: 1, active: false, notificationFk: 1 }];
|
||||||
|
|
||||||
|
await vm.toggleNotification(vm.notifications[0]);
|
||||||
|
|
||||||
|
expect(vm.notifications[0].id).toBe(null);
|
||||||
|
expect(vm.notifications[0].active).toBeFalsy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue