salix-front/src/pages/Worker/Card/WorkerNotificationsManager.vue

155 lines
4.6 KiB
Vue

<script setup>
import axios from 'axios';
import { useQuasar } from 'quasar';
import { computed, ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { useRoute } from 'vue-router';
import CrudModel from 'components/CrudModel.vue';
const $props = defineProps({
id: {
type: Number,
required: false,
default: null,
},
});
const route = useRoute();
const { t } = useI18n();
const quasar = useQuasar();
const entityId = computed(() => $props.id || route.params.id);
const URL_KEY = 'NotificationSubscriptions';
const active = ref(new Map());
const available = ref(new Map());
async function toggleNotification(notification) {
try {
if (!notification.active) {
await axios.delete(`${URL_KEY}/${notification.id}`);
swapEntry(active.value, available.value, notification.notificationFk);
} else {
const { data } = await axios.post(URL_KEY, {
notificationFk: notification.notificationFk,
userFk: entityId.value,
});
notification.id = data.id;
swapEntry(available.value, active.value, notification.notificationFk);
}
quasar.notify({
type: 'positive',
message: t(
`worker.notificationsManager.${notification.active ? '' : 'un'}subscribed`
),
});
} catch (e) {
notification.active = !notification.active;
throw e;
}
}
const swapEntry = (from, to, key) => {
const element = from.get(key);
to.set(key, element);
from.delete(key);
};
function setNotifications(data) {
active.value = new Map(data.active);
available.value = new Map(data.available);
}
</script>
<template>
<CrudModel
auto-load
:data-key="URL_KEY"
:url="`${URL_KEY}/${entityId}/getList`"
:default-reset="false"
:default-remove="false"
:default-save="false"
@on-fetch="(data) => data && setNotifications(data)"
search-url="notifications"
>
<template #body>
<div
v-for="(notifications, index) in [
[...active.values()],
[...available.values()],
]"
:key="notifications"
>
<QList class="notificationList">
<TransitionGroup>
<QCard
v-for="notification in notifications"
:key="notification.notificationFk"
class="q-pa-md"
>
<QItem>
<QItemSection avatar>
<QBtn
round
icon="mail"
:color="notification.active ? 'green' : 'grey'"
/>
</QItemSection>
<QItemSection>
<QItemLabel>{{ notification.name }}</QItemLabel>
<QItemLabel caption>
{{ notification.description }}
</QItemLabel>
</QItemSection>
<QToggle
checked-icon="check"
unchecked-icon="close"
v-model="notification.active"
color="green"
@update:model-value="toggleNotification(notification)"
/>
</QItem>
</QCard>
</TransitionGroup>
</QList>
<QSeparator
color="primary"
class="q-my-lg"
v-if="!index && available.size && active.size"
/>
</div>
</template>
</CrudModel>
</template>
<style lang="scss" scoped>
.notificationList {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-gap: 10px;
.v-enter-active,
.v-leave-active {
transition: opacity 0.5s ease;
}
.v-enter-from,
.v-leave-to {
opacity: 0;
}
}
@media (max-width: $breakpoint-md) {
.notificationList {
grid-template-columns: repeat(2, 1fr);
}
}
@media (max-width: $breakpoint-xs) {
.notificationList {
grid-template-columns: repeat(1, 1fr);
}
}
</style>