ADD: Administrar roles (#4)

This commit is contained in:
Moisés de Jesús Cortés Castellanos 2024-12-28 13:50:41 -06:00 committed by GitHub
parent 24edbfebb4
commit df7e8bf2ec
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
23 changed files with 920 additions and 590 deletions

663
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@
"name": "notsoweb.frontend",
"copyright": "Notsoweb Software Inc.",
"private": true,
"version": "0.9.3",
"version": "0.9.4",
"type": "module",
"scripts": {
"dev": "vite",

View File

@ -0,0 +1,44 @@
<script setup>
import { computed } from 'vue';
import { v4 as uuidv4 } from 'uuid';
const emit = defineEmits([
'update:modelValue'
]);
const uuid = uuidv4();
const props = defineProps({
title: String,
modelValue: Object | Boolean,
value: Object | Boolean,
});
const vModel = computed({
get() {
return props.modelValue;
},
set(value) {
emit('update:modelValue', value);
},
});
</script>
<template>
<div class="relative w-full h-8">
<input
class="appearance-none rounded-lg bg-primary cursor-pointer h-full w-full checked:bg-secondary dark:checked:bg-secondary-d transition-all duration-200 peer"
type="checkbox"
:id="uuid"
v-model="vModel"
:value="value"
/>
<label
:for="uuid"
class="absolute top-[50%] left-3 text-primary-t dark:text-primary-dt -translate-y-[50%] peer-checked:text-white dark:peer-checked:text-primary-dt transition-all duration-200 select-none"
>
{{ title }}
</label>
</div>
</template>

View File

@ -7,7 +7,7 @@ import { useRoute, ZiggyVue } from 'ziggy-js';
import { i18n, lang } from '@Lang/i18n.js';
import router from '@Router/Index'
import Notify from '@Plugins/Notify'
import { bootPermissions } from '@Plugins/RolePermission';
import { bootPermissions, bootRoles } from '@Plugins/RolePermission';
import TailwindScreen from '@Plugins/TailwindScreen'
import { pagePlugin } from '@Services/Page';
import { reloadApp, view } from '@Services/Page';
@ -42,6 +42,7 @@ async function boot() {
if(initRoutes) {
// Iniciar permisos
await bootPermissions();
await bootRoles();
// Iniciar broadcast
if(import.meta.env.VITE_REVERB_ACTIVE === 'true') {

View File

@ -251,6 +251,7 @@ export default {
profile:'Perfil',
readed:'Leído',
read_at:'Fecha leído',
refresh: 'Recargar',
register: {
create: {
onError: 'Error al crear el registro',
@ -294,11 +295,17 @@ export default {
deleted:'Rol eliminado',
edit: {
title: 'Editar rol',
description: 'Actualiza los permisos del rol.',
onSuccess: 'Rol actualizado exitosamente',
onError: 'Error al actualizar el role',
},
update: {
description: 'Actualiza los permisos del rol.',
},
title: 'Roles',
permissions: {
title: 'Permisos',
description: 'Permisos del rol.',
}
},
save:'Guardar',
saved:'¡Guardado!',

View File

@ -50,6 +50,12 @@ onMounted(() => {
name="users.title"
to="admin.users.index"
/>
<Link
v-if="hasPermission('roles.index')"
icon="license"
name="roles.title"
to="admin.roles.index"
/>
</Section>
</template>
<!-- Contenido -->

View File

@ -0,0 +1,45 @@
<script setup>
import { useRouter } from 'vue-router';
import { useForm } from '@Services/Api';
import { apiTo, transl, viewTo } from './Module';
import IconButton from '@Holos/Button/Icon.vue'
import PageHeader from '@Holos/PageHeader.vue';
import Form from './Form.vue'
/** Definidores */
const router = useRouter();
/** Propiedades */
const form = useForm({
description: '',
});
/** Métodos */
function submit() {
form.post(apiTo('store'), {
onSuccess: () => {
Notify.success(Lang('register.create.onSuccess'))
router.push(viewTo({ name: 'index' }));
}
})
}
</script>
<template>
<PageHeader :title="transl('create.title')">
<RouterLink :to="viewTo({ name: 'index' })">
<IconButton
class="text-white"
icon="arrow_back"
:title="$t('return')"
filled
/>
</RouterLink>
</PageHeader>
<Form
action="create"
:form="form"
@submit="submit"
/>
</template>

View File

@ -0,0 +1,54 @@
<script setup>
import { onMounted } from 'vue';
import { RouterLink, useRoute, useRouter } from 'vue-router';
import { api, useForm } from '@Services/Api';
import { viewTo, apiTo , transl } from './Module';
import IconButton from '@Holos/Button/Icon.vue'
import PageHeader from '@Holos/PageHeader.vue';
import Form from './Form.vue'
/** Definiciones */
const vroute = useRoute();
const router = useRouter();
/** Propiedades */
const form = useForm({
id: null,
description: '',
});
/** Métodos */
function submit() {
form.put(apiTo('update', { role: form.id }), {
onSuccess: () => {
Notify.success(Lang('register.edit.onSuccess'))
router.push(viewTo({ name: 'index' }));
},
})
}
onMounted(() => {
api.get(apiTo('show', { role: vroute.params.id }), {
onSuccess: (r) => form.fill(r.model)
});
})
</script>
<template>
<PageHeader :title="transl('edit.title')">
<RouterLink :to="viewTo({ name: 'index' })">
<IconButton
class="text-white"
icon="arrow_back"
:title="$t('return')"
filled
/>
</RouterLink>
</PageHeader>
<Form
action="update"
:form="form"
@submit="submit"
/>
</template>

View File

@ -0,0 +1,50 @@
<script setup>
import { transl } from './Module';
import PrimaryButton from '@Holos/Button/Primary.vue';
import Input from '@Holos/Form/Input.vue';
/** Eventos */
const emit = defineEmits([
'submit'
])
/** Propiedades */
defineProps({
action: {
default: 'create',
type: String
},
form: Object
})
/** Métodos */
function submit() {
emit('submit')
}
</script>
<template>
<div class="w-full py-4">
<p class="text-justify text-sm" v-text="transl(`${action}.description`)" />
</div>
<div class="w-full">
<form @submit.prevent="submit" class="grid gap-4 grid-cols-1">
<Input
v-model="form.description"
id="name"
:onError="form.errors.description"
autofocus
required
/>
<slot />
<div class="flex flex-col items-center justify-end space-y-4 mt-4">
<PrimaryButton
v-text="$t(action)"
:class="{ 'opacity-25': form.processing }"
:disabled="form.processing"
/>
</div>
</form>
</div>
</template>

View File

@ -0,0 +1,127 @@
<script setup>
import { onMounted, ref } from 'vue';
import { can, apiTo, viewTo } from './Module'
import { useSearcher } from '@Services/Api';
import ModalController from '@Controllers/ModalController.js';
import IconButton from '@Holos/Button/Icon.vue'
import DestroyView from '@Holos/Modal/Template/Destroy.vue';
import SearcherHead from '@Holos/Searcher.vue';
import Table from '@Holos/Table.vue';
import Permissions from './Modals/Permissions.vue';
/** Controladores */
const Modal = new ModalController();
/** Propiedades */
const destroyModal = ref(Modal.destroyModal);
const editModal = ref(Modal.editModal);
const modelModal = ref(Modal.modelModal);
const models = ref([]);
const searcher = useSearcher({
url: route('roles.index'),
onSuccess: (r) => models.value = r.models,
onError: () => models.value = []
});
/** Ciclos */
onMounted(() => {
searcher.search();
});
</script>
<template>
<div>
<SearcherHead
:title="$t('roles.title')"
@search="(x) => searcher.search(x)"
>
<RouterLink
v-if="can('create')"
:to="viewTo({ name: 'create' })"
>
<IconButton
class="text-white"
icon="add"
:title="$t('crud.create')"
filled
/>
</RouterLink>
<IconButton
icon="refresh"
:title="$t('refresh')"
@click="searcher.search()"
/>
</SearcherHead>
<div class="pt-2 w-full">
<Table
:items="models"
@send-pagination="searcher.pagination"
:processing="searcher.processing"
>
<template #head>
<th v-text="$t('name')" />
<th
v-text="$t('actions')"
class="w-32 text-center"
/>
</template>
<template #body="{items}">
<tr v-for="model in items">
<td class="table-item border">
{{ model.description }}
</td>
<td class="table-item">
<div class="table-actions">
<IconButton
v-if="can('edit') && ![1,2].includes(model.id)"
icon="license"
:title="$t('roles.permissions.title')"
@click="Modal.switchEditModal(model)"
outline
/>
<RouterLink
v-if="can('edit')"
class="h-fit"
:to="viewTo({ name: 'edit', params: { id: model.id } })"
>
<IconButton
icon="edit"
:title="$t('crud.edit')"
outline
/>
</RouterLink>
<IconButton
v-if="can('destroy') && ![1,2].includes(model.id)"
icon="delete"
:title="$t('crud.destroy')"
@click="Modal.switchDestroyModal(model)"
outline
/>
</div>
</td>
</tr>
</template>
</Table>
</div>
<Permissions
v-if="can('index')"
:show="editModal"
:model="modelModal"
@close="Modal.switchEditModal"
/>
<DestroyView
v-if="can('destroy')"
:model="modelModal"
:show="destroyModal"
:to="(role) => apiTo('destroy', { role })"
@close="Modal.switchDestroyModal"
@update="searcher.search()"
/>
</div>
</template>

View File

@ -0,0 +1,80 @@
<script setup>
import { onUpdated, ref } from 'vue';
import { api } from '@Services/Api';
import Header from '@Holos/Modal/Elements/Header.vue';
import EditModal from '@Holos/Modal/Edit.vue';
import Checkbox from '@Holos/Form/Checkbox.vue';
/** Eventos */
const emit = defineEmits([
'close',
]);
/** Propiedades */
const props = defineProps({
show: Boolean,
model: Object
});
const permissionTypes = ref([]);
const permissions = ref([]);
/** Métodos */
function update() {
api.put(route('roles.permissions', { role: props.model.id }), {
data: {
permissions: permissions.value
},
onSuccess: () => {
Notify.success(Lang('register.edit.onSuccess'))
emit('close');
}
});
}
/** Ciclos */
onUpdated(() => {
api.get(route('permission-types.all-with-permissions'), {
onSuccess: (r) => permissionTypes.value = r.models
});
api.get(route('roles.permissions', { role: props.model.id }), {
onSuccess: (r) => {
if(r.permissions) {
permissions.value = r.permissions.map(p => p.id);
}
}
});
});
</script>
<template>
<EditModal
:show="show"
@update="update"
@close="$emit('close')"
>
<Header
:title="model.description"
/>
<div class="p-4 border-b">
<div class="grid gap-4 grid-cols-2">
<div v-for="permissionType in permissionTypes">
<div>
<p class="font-bold">{{ permissionType.name}}</p>
<ul class="space-y-0.5 list-none">
<li v-for="permission in permissionType.permissions">
<Checkbox
v-model="permissions"
:title="permission.description"
:value="permission.id"
/>
</li>
</ul>
</div>
</div>
</div>
</div>
</EditModal>
</template>

View File

@ -0,0 +1,21 @@
import { lang } from '@Lang/i18n';
import { hasPermission } from '@Plugins/RolePermission.js';
// Ruta API
const apiTo = (name, params = {}) => route(`roles.${name}`, params)
// Ruta visual
const viewTo = ({ name = '', params = {}, query = {} }) => view({ name: `admin.roles.${name}`, params, query })
// Obtener traducción del componente
const transl = (str) => lang(`roles.${str}`)
// Determina si un usuario puede hacer algo no en base a los permisos
const can = (permission) => hasPermission(`roles.${permission}`)
export {
can,
viewTo,
apiTo,
transl
}

View File

@ -2,16 +2,14 @@
import { onMounted, ref } from 'vue';
import { can, apiTo, viewTo } from './Module'
import { useSearcher } from '@Services/Api';
import { users } from '@Plugins/AuthUsers'
import ModalController from '@Controllers/ModalController.js';
import IconButton from '@Holos/Button/Icon.vue'
import DestroyView from '@Holos/Modal/Template/Destroy.vue';
import SearcherHead from '@Holos/Searcher.vue';
import Table from '@Holos/Table.vue';
import GoogleIcon from '@Shared/GoogleIcon.vue';
import ShowView from './Modals/Show.vue';
import IconButton from '@Holos/Button/Icon.vue'
import DestroyView from '@Holos/Modal/Template/Destroy.vue';
import SearcherHead from '@Holos/Searcher.vue';
import Table from '@Holos/Table.vue';
import ShowView from './Modals/Show.vue';
/** Controladores */
const Modal = new ModalController();
@ -52,6 +50,11 @@ onMounted(() => {
filled
/>
</RouterLink>
<IconButton
icon="refresh"
:title="$t('refresh')"
@click="searcher.search()"
/>
</SearcherHead>
<div class="pt-2 w-full">
<Table
@ -95,9 +98,8 @@ onMounted(() => {
</td>
<td class="table-item">
<div class="table-actions">
<GoogleIcon
class="btn-icon"
name="visibility"
<IconButton
icon="visibility"
:title="$t('crud.show')"
@click="Modal.switchShowModal(model)"
outline
@ -107,17 +109,15 @@ onMounted(() => {
class="h-fit"
:to="viewTo({ name: 'edit', params: { id: model.id } })"
>
<GoogleIcon
class="btn-icon"
name="edit"
<IconButton
icon="edit"
:title="$t('crud.edit')"
outline
/>
</RouterLink>
<GoogleIcon
<IconButton
v-if="can('destroy')"
class="btn-icon"
name="delete"
icon="delete"
:title="$t('crud.destroy')"
@click="Modal.switchDestroyModal(model)"
outline
@ -127,9 +127,8 @@ onMounted(() => {
class="h-fit"
:to="viewTo({ name: 'settings', params: { id: model.id } })"
>
<GoogleIcon
class="btn-icon"
name="settings"
<IconButton
icon="settings"
:title="$t('setting')"
/>
</RouterLink>

View File

@ -9,7 +9,6 @@ import IconButton from '@Holos/Button/Icon.vue'
import DestroyView from '@Holos/Modal/Template/Destroy.vue';
import Header from '@Holos/PageHeader.vue';
import Table from '@Holos/TableSimple.vue';
import GoogleIcon from '@Shared/GoogleIcon.vue';
import ShowView from './Modals/Show.vue';
/** Controladores */
@ -85,9 +84,8 @@ const modelModal = ref(Modal.modelModal);
</td>
<td class="table-item">
<div class="table-actions">
<GoogleIcon
class="btn-icon"
name="visibility"
<IconButton
icon="visibility"
:title="$t('crud.show')"
@click="Modal.switchShowModal(model)"
outline
@ -97,17 +95,15 @@ const modelModal = ref(Modal.modelModal);
class="h-fit"
:to="viewTo({ name: 'edit', params: { id: model.id } })"
>
<GoogleIcon
class="btn-icon"
name="edit"
<IconButton
icon="edit"
:title="$t('crud.edit')"
outline
/>
</RouterLink>
<GoogleIcon
<IconButton
v-if="can('destroy')"
class="btn-icon"
name="delete"
icon="delete"
:title="$t('crud.destroy')"
@click="Modal.switchDestroyModal(model)"
outline
@ -117,9 +113,8 @@ const modelModal = ref(Modal.modelModal);
class="h-fit"
:to="viewTo({ name: 'settings', params: { id: model.id } })"
>
<GoogleIcon
class="btn-icon"
name="settings"
<IconButton
icon="settings"
:title="$t('setting')"
/>
</RouterLink>

View File

@ -1,99 +0,0 @@
<script setup>
import { ref } from 'vue';
import { Link } from '@inertiajs/vue3';
import { transl, can, viewTo } from './Module'
import ModalController from '@Controllers/ModalController.js';
import SearcherController from '@Controllers/SearcherController.js';
import InboxController from '@Controllers/InboxController.js';
import Inbox from '@Holos/Inbox.vue';
import InboxItem from '@Holos/Inbox/Item.vue';
import SearcherHead from '@Holos/Searcher.vue';
import DashboardLayout from '@Layouts/AppLayout.vue';
import Menu from './Partials/Menu.vue';
import ItemRow from './Partials/ItemRow.vue';
import ShowView from './Modals/Show.vue';
import GoogleIcon from '@/Components/Shared/GoogleIcon.vue';
/** Definidores */
const inboxCtl = new InboxController();
const searcherCtl = new SearcherController(viewTo('index'));
/** Eventos */
const props = defineProps({
models: Object
});
/** Controladores */
const Modal = new ModalController();
/** Propiedades */
const showModal = ref(Modal.showModal);
const modelModal = ref(Modal.modelModal);
</script>
<template>
<DashboardLayout :title="transl('system')">
<SearcherHead @search="searcherCtl.search" />
<Inbox
:inboxCtl="inboxCtl"
:items="models"
:searcherCtl="searcherCtl"
withMultiSelection
>
<template #menu>
<Menu
:counters="counters"
/>
</template>
<template #actions>
<div class="flex items-center ml-3">
<GoogleIcon
class="inbox-icon"
title="Enviar a almacén"
name="warehouse"
outline
@click="sendToWarehouse()"
/>
</div>
</template>
<template #head>
</template>
<template #items="{items}">
<template v-for="model in items" :key="model.id">
<InboxItem
:inboxCtl="inboxCtl"
:item="model"
>
<template #item>
<ItemRow
:model="model"
/>
</template>
<template #actions="{check}">
</template>
<template #date>
<span>{{ model.tracker}}</span>
</template>
</InboxItem>
</template>
</template>
</Inbox>
<ShowView
v-if="can('index')"
:show="showModal"
:model="modelModal"
@close="Modal.switchShowModal"
/>
</DashboardLayout>
</template>

View File

@ -1,53 +0,0 @@
<script setup>
import Header from '@Holos/Modal/Elements/Header.vue';
import ShowModal from '@Holos/Modal/Show.vue';
import GoogleIcon from '@Shared/GoogleIcon.vue';
/** Eventos */
defineEmits([
'close',
]);
/** Propiedades */
defineProps({
show: Boolean,
model: Object
});
</script>
<template>
<ShowModal
:show="show"
@close="$emit('close')"
>
<Header
:title="model.name"
:subtitle="model.full_last_name"
>
</Header>
<div class="py-2 border-b">
<div class="px-4 py-2 flex">
<GoogleIcon
class="text-xl text-success"
name="contact_mail"
/>
<div class="pl-3">
<p class="font-bold text-lg leading-none pb-2">
{{ $t('contact') }}
</p>
<p>
<b>{{ $t('phone') }}: </b>
<a :href="`tel:${model.phone}`" target="_blank" class="hover:text-danger">
{{ model.phone }}
</a>
</p>
<p>
<b>{{ $t('email') }}: </b>
<a :href="`mailto:${model.email}`" target="_blank" class="hover:text-danger">
{{ model.email }}
</a>
</p>
</div>
</div>
</div>
</ShowModal>
</template>

View File

@ -1,15 +0,0 @@
import { lang } from '@/Lang/i18n';
import { hasPermission } from '@Plugins/RolePermission.js';
// Obtener ruta
const viewTo = (route) => `admin.users.${route}`
// Obtener traducción del componente
const transl = (str) => lang(`notifications.${str}`)
// Determina si un usuario puede hacer algo no en base a los permisos
const can = (permission) => hasPermission(`users.${permission}`)
export {
can,
viewTo,
transl
}

View File

@ -1,18 +0,0 @@
<script setup>
defineProps({
model: Object
})
</script>
<template>
<span class="w-48 pr-2 truncate">
{{ model.data.title }}
</span>
<span class="w-full pr-2 truncate">
{{ model.data.description }}
</span>
<span class="w-28 pr-2 truncate">
{{ model.data.type}}
</span>
</template>

View File

@ -1,29 +0,0 @@
<script setup>
import InboxMenuItem from '@Holos/Inbox/Menu/Item.vue';
/** Propiedades */
const props = defineProps({
counters: Object,
});
</script>
<template>
<InboxMenuItem
icon="people"
title="all"
to="notifications.index"
:counter="counters?.all"
/>
<InboxMenuItem
icon="local_shipping"
title="notifications.readed"
to="notifications.readed"
:counter="counters?.readed"
/>
<InboxMenuItem
icon="replay"
title="notifications.unreaded"
to="notifications.unreaded"
:counter="counters?.unreaded"
/>
</template>

View File

@ -7,9 +7,9 @@ import { getDateTime } from '@Controllers/DateController.js';
import SearcherHead from '@Holos/Searcher.vue';
import Table from '@Holos/Table.vue';
import GoogleIcon from '@Shared/GoogleIcon.vue';
import IconButton from '@Holos/Button/Icon.vue';
import ShowView from '@Holos/Skeleton/Sidebar/Notification/Show.vue';
import GoogleIcon from '@Shared/GoogleIcon.vue';
/** Controladores */
const Modal = new ModalController();
@ -41,7 +41,7 @@ onMounted(() => {
>
<IconButton
icon="refresh"
:title="$t('notifications.unreadClosed')"
:title="$t('refresh')"
@click="searcher.search()"
/>
</SearcherHead>
@ -86,9 +86,8 @@ onMounted(() => {
</td>
<td class="table-item">
<div class="table-actions">
<GoogleIcon
class="btn-icon"
name="visibility"
<IconButton
icon="visibility"
:title="$t('crud.show')"
@click="Modal.switchShowModal(model)"
outline

View File

@ -3,6 +3,9 @@ import { api } from '@Services/Api';
const permissionsInit = ref(false)
const allPermissions = ref([])
const rolesInit = ref(false)
const allRoles = ref([])
const allRolesIds = ref([])
/**
* Permite consultar si un usuario tiene un permiso especifico
@ -11,10 +14,20 @@ const hasPermission = (can) => {
let verifyPermissions = can.split('|');
for (let permision in verifyPermissions) {
if(allPermissions.value.length != 0) {
if(allPermissions.value.indexOf(verifyPermissions[permision]) != -1) {
return true;
}
if(allPermissions.value.indexOf(verifyPermissions[permision]) != -1) {
return true;
}
}
return false;
}
const hasRole = (role) => {
let verifyRoles = role.split('|');
for (let role in verifyRoles) {
if(allRoles.value.indexOf(verifyRoles[role]) != -1) {
return true;
}
}
@ -41,15 +54,66 @@ const bootPermissions = () => {
})
}
const bootRoles = () => {
return new Promise((resolve, reject) => {
if (!rolesInit.value) {
api.get(route('user.roles'), {
onSuccess: (res) => {
loadRoles(res.roles)
resolve(true)
},
onFinish: () => {
rolesInit.value = true;
},
onError: () => {
reject(false)
}
})
}
})
}
const reloadPermissions = () => {
permissionsInit.value = false;
bootPermissions()
}
const reloadRoles = () => {
rolesInit.value = false;
bootRoles()
}
const resetPermissions = () => {
allPermissions.value = [];
permissionsInit.value = false;
}
const resetRoles = () => {
allRoles.value = [];
rolesInit.value = false;
}
const loadPermissions = (permissionList = []) => {
// Permisos cargados
let currentPermissions = [];
if (permissionList.length > 0) {
permissionList.forEach(element => {
allPermissions.value.push(element.name)
currentPermissions.push(element.name)
});
}
allPermissions.value = currentPermissions;
}
const loadRoles = (roleList = []) => {
if (roleList.length > 0) {
roleList.forEach(element => {
allRoles.value.push(element.name)
allRolesIds.value.push(element.id)
});
}
}
@ -58,9 +122,24 @@ const getAllPermissions = () => {
return allPermissions.value;
}
const getAllRoles = () => {
return allRoles.value;
}
const getAllRolesIds = () => {
return allRolesIds.value;
}
export {
bootPermissions,
bootRoles,
hasPermission,
hasRole,
reloadPermissions,
reloadRoles,
resetPermissions,
getAllPermissions
resetRoles,
getAllPermissions,
getAllRoles,
getAllRolesIds
};

View File

@ -71,6 +71,25 @@ const router = createRouter({
}
]
},
{
path: 'roles',
children: [
{
path: '',
name: 'admin.roles.index',
component: () => import('@Pages/Admin/Roles/Index.vue')
},
{
path: 'create',
name: 'admin.roles.create',
component: () => import('@Pages/Admin/Roles/Create.vue')
}, {
path: ':id/edit',
name: 'admin.roles.edit',
component: () => import('@Pages/Admin/Roles/Edit.vue')
}
]
}
]
},
{

View File

@ -1,7 +1,7 @@
import { defineStore } from 'pinia'
import { api } from '@Services/Api'
import { page } from '@Services/Page'
import { hasPermission } from '@Plugins/RolePermission'
import { hasPermission, reloadPermissions, getAllRolesIds } from '@Plugins/RolePermission'
import { boot as bootAuthUsers, addUser, removeUser } from '@Plugins/AuthUsers'
/** Propiedades */
@ -25,6 +25,7 @@ const useNotifier = defineStore('notifier', {
this.subscribeGLobalNotifications();
this.subscribeUserNotifications();
this.suscribeAuthUsers();
this.suscribeRoles();
this.isStarted = true;
this.getUpdates();
@ -68,6 +69,18 @@ const useNotifier = defineStore('notifier', {
Echo.join('online');
}
},
suscribeRoles() {
const roles = getAllRolesIds();
roles.forEach(role => {
Echo.private(`App.Models.Role.${role}`)
.listen('UpdateRoleUser', e => {
reloadPermissions();
Notify.success(`Actualizando permisos de ${e.role.description}`)
});
});
},
// Notificaciones del usuario
subscribeUserNotifications() {
Echo.private(`App.Models.User.${this.user_id}`)