ADD: Administrar roles (#4)
This commit is contained in:
parent
24edbfebb4
commit
df7e8bf2ec
663
package-lock.json
generated
663
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -2,7 +2,7 @@
|
|||||||
"name": "notsoweb.frontend",
|
"name": "notsoweb.frontend",
|
||||||
"copyright": "Notsoweb Software Inc.",
|
"copyright": "Notsoweb Software Inc.",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.9.3",
|
"version": "0.9.4",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
|
|||||||
44
src/components/Holos/Form/Checkbox.vue
Normal file
44
src/components/Holos/Form/Checkbox.vue
Normal 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>
|
||||||
@ -7,7 +7,7 @@ import { useRoute, ZiggyVue } from 'ziggy-js';
|
|||||||
import { i18n, lang } from '@Lang/i18n.js';
|
import { i18n, lang } from '@Lang/i18n.js';
|
||||||
import router from '@Router/Index'
|
import router from '@Router/Index'
|
||||||
import Notify from '@Plugins/Notify'
|
import Notify from '@Plugins/Notify'
|
||||||
import { bootPermissions } from '@Plugins/RolePermission';
|
import { bootPermissions, bootRoles } from '@Plugins/RolePermission';
|
||||||
import TailwindScreen from '@Plugins/TailwindScreen'
|
import TailwindScreen from '@Plugins/TailwindScreen'
|
||||||
import { pagePlugin } from '@Services/Page';
|
import { pagePlugin } from '@Services/Page';
|
||||||
import { reloadApp, view } from '@Services/Page';
|
import { reloadApp, view } from '@Services/Page';
|
||||||
@ -42,6 +42,7 @@ async function boot() {
|
|||||||
if(initRoutes) {
|
if(initRoutes) {
|
||||||
// Iniciar permisos
|
// Iniciar permisos
|
||||||
await bootPermissions();
|
await bootPermissions();
|
||||||
|
await bootRoles();
|
||||||
|
|
||||||
// Iniciar broadcast
|
// Iniciar broadcast
|
||||||
if(import.meta.env.VITE_REVERB_ACTIVE === 'true') {
|
if(import.meta.env.VITE_REVERB_ACTIVE === 'true') {
|
||||||
|
|||||||
@ -251,6 +251,7 @@ export default {
|
|||||||
profile:'Perfil',
|
profile:'Perfil',
|
||||||
readed:'Leído',
|
readed:'Leído',
|
||||||
read_at:'Fecha leído',
|
read_at:'Fecha leído',
|
||||||
|
refresh: 'Recargar',
|
||||||
register: {
|
register: {
|
||||||
create: {
|
create: {
|
||||||
onError: 'Error al crear el registro',
|
onError: 'Error al crear el registro',
|
||||||
@ -294,11 +295,17 @@ export default {
|
|||||||
deleted:'Rol eliminado',
|
deleted:'Rol eliminado',
|
||||||
edit: {
|
edit: {
|
||||||
title: 'Editar rol',
|
title: 'Editar rol',
|
||||||
description: 'Actualiza los permisos del rol.',
|
|
||||||
onSuccess: 'Rol actualizado exitosamente',
|
onSuccess: 'Rol actualizado exitosamente',
|
||||||
onError: 'Error al actualizar el role',
|
onError: 'Error al actualizar el role',
|
||||||
},
|
},
|
||||||
|
update: {
|
||||||
|
description: 'Actualiza los permisos del rol.',
|
||||||
|
},
|
||||||
title: 'Roles',
|
title: 'Roles',
|
||||||
|
permissions: {
|
||||||
|
title: 'Permisos',
|
||||||
|
description: 'Permisos del rol.',
|
||||||
|
}
|
||||||
},
|
},
|
||||||
save:'Guardar',
|
save:'Guardar',
|
||||||
saved:'¡Guardado!',
|
saved:'¡Guardado!',
|
||||||
|
|||||||
@ -50,6 +50,12 @@ onMounted(() => {
|
|||||||
name="users.title"
|
name="users.title"
|
||||||
to="admin.users.index"
|
to="admin.users.index"
|
||||||
/>
|
/>
|
||||||
|
<Link
|
||||||
|
v-if="hasPermission('roles.index')"
|
||||||
|
icon="license"
|
||||||
|
name="roles.title"
|
||||||
|
to="admin.roles.index"
|
||||||
|
/>
|
||||||
</Section>
|
</Section>
|
||||||
</template>
|
</template>
|
||||||
<!-- Contenido -->
|
<!-- Contenido -->
|
||||||
|
|||||||
45
src/pages/Admin/Roles/Create.vue
Normal file
45
src/pages/Admin/Roles/Create.vue
Normal 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>
|
||||||
54
src/pages/Admin/Roles/Edit.vue
Normal file
54
src/pages/Admin/Roles/Edit.vue
Normal 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>
|
||||||
50
src/pages/Admin/Roles/Form.vue
Normal file
50
src/pages/Admin/Roles/Form.vue
Normal 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>
|
||||||
127
src/pages/Admin/Roles/Index.vue
Normal file
127
src/pages/Admin/Roles/Index.vue
Normal 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>
|
||||||
|
|
||||||
80
src/pages/Admin/Roles/Modals/Permissions.vue
Normal file
80
src/pages/Admin/Roles/Modals/Permissions.vue
Normal 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>
|
||||||
21
src/pages/Admin/Roles/Module.js
Normal file
21
src/pages/Admin/Roles/Module.js
Normal 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
|
||||||
|
}
|
||||||
@ -2,16 +2,14 @@
|
|||||||
import { onMounted, ref } from 'vue';
|
import { onMounted, ref } from 'vue';
|
||||||
import { can, apiTo, viewTo } from './Module'
|
import { can, apiTo, viewTo } from './Module'
|
||||||
import { useSearcher } from '@Services/Api';
|
import { useSearcher } from '@Services/Api';
|
||||||
import { users } from '@Plugins/AuthUsers'
|
|
||||||
|
|
||||||
import ModalController from '@Controllers/ModalController.js';
|
import ModalController from '@Controllers/ModalController.js';
|
||||||
|
|
||||||
import IconButton from '@Holos/Button/Icon.vue'
|
import IconButton from '@Holos/Button/Icon.vue'
|
||||||
import DestroyView from '@Holos/Modal/Template/Destroy.vue';
|
import DestroyView from '@Holos/Modal/Template/Destroy.vue';
|
||||||
import SearcherHead from '@Holos/Searcher.vue';
|
import SearcherHead from '@Holos/Searcher.vue';
|
||||||
import Table from '@Holos/Table.vue';
|
import Table from '@Holos/Table.vue';
|
||||||
import GoogleIcon from '@Shared/GoogleIcon.vue';
|
import ShowView from './Modals/Show.vue';
|
||||||
import ShowView from './Modals/Show.vue';
|
|
||||||
|
|
||||||
/** Controladores */
|
/** Controladores */
|
||||||
const Modal = new ModalController();
|
const Modal = new ModalController();
|
||||||
@ -52,6 +50,11 @@ onMounted(() => {
|
|||||||
filled
|
filled
|
||||||
/>
|
/>
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
|
<IconButton
|
||||||
|
icon="refresh"
|
||||||
|
:title="$t('refresh')"
|
||||||
|
@click="searcher.search()"
|
||||||
|
/>
|
||||||
</SearcherHead>
|
</SearcherHead>
|
||||||
<div class="pt-2 w-full">
|
<div class="pt-2 w-full">
|
||||||
<Table
|
<Table
|
||||||
@ -95,9 +98,8 @@ onMounted(() => {
|
|||||||
</td>
|
</td>
|
||||||
<td class="table-item">
|
<td class="table-item">
|
||||||
<div class="table-actions">
|
<div class="table-actions">
|
||||||
<GoogleIcon
|
<IconButton
|
||||||
class="btn-icon"
|
icon="visibility"
|
||||||
name="visibility"
|
|
||||||
:title="$t('crud.show')"
|
:title="$t('crud.show')"
|
||||||
@click="Modal.switchShowModal(model)"
|
@click="Modal.switchShowModal(model)"
|
||||||
outline
|
outline
|
||||||
@ -107,17 +109,15 @@ onMounted(() => {
|
|||||||
class="h-fit"
|
class="h-fit"
|
||||||
:to="viewTo({ name: 'edit', params: { id: model.id } })"
|
:to="viewTo({ name: 'edit', params: { id: model.id } })"
|
||||||
>
|
>
|
||||||
<GoogleIcon
|
<IconButton
|
||||||
class="btn-icon"
|
icon="edit"
|
||||||
name="edit"
|
|
||||||
:title="$t('crud.edit')"
|
:title="$t('crud.edit')"
|
||||||
outline
|
outline
|
||||||
/>
|
/>
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
<GoogleIcon
|
<IconButton
|
||||||
v-if="can('destroy')"
|
v-if="can('destroy')"
|
||||||
class="btn-icon"
|
icon="delete"
|
||||||
name="delete"
|
|
||||||
:title="$t('crud.destroy')"
|
:title="$t('crud.destroy')"
|
||||||
@click="Modal.switchDestroyModal(model)"
|
@click="Modal.switchDestroyModal(model)"
|
||||||
outline
|
outline
|
||||||
@ -127,9 +127,8 @@ onMounted(() => {
|
|||||||
class="h-fit"
|
class="h-fit"
|
||||||
:to="viewTo({ name: 'settings', params: { id: model.id } })"
|
:to="viewTo({ name: 'settings', params: { id: model.id } })"
|
||||||
>
|
>
|
||||||
<GoogleIcon
|
<IconButton
|
||||||
class="btn-icon"
|
icon="settings"
|
||||||
name="settings"
|
|
||||||
:title="$t('setting')"
|
:title="$t('setting')"
|
||||||
/>
|
/>
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
|
|||||||
@ -9,7 +9,6 @@ import IconButton from '@Holos/Button/Icon.vue'
|
|||||||
import DestroyView from '@Holos/Modal/Template/Destroy.vue';
|
import DestroyView from '@Holos/Modal/Template/Destroy.vue';
|
||||||
import Header from '@Holos/PageHeader.vue';
|
import Header from '@Holos/PageHeader.vue';
|
||||||
import Table from '@Holos/TableSimple.vue';
|
import Table from '@Holos/TableSimple.vue';
|
||||||
import GoogleIcon from '@Shared/GoogleIcon.vue';
|
|
||||||
import ShowView from './Modals/Show.vue';
|
import ShowView from './Modals/Show.vue';
|
||||||
|
|
||||||
/** Controladores */
|
/** Controladores */
|
||||||
@ -85,9 +84,8 @@ const modelModal = ref(Modal.modelModal);
|
|||||||
</td>
|
</td>
|
||||||
<td class="table-item">
|
<td class="table-item">
|
||||||
<div class="table-actions">
|
<div class="table-actions">
|
||||||
<GoogleIcon
|
<IconButton
|
||||||
class="btn-icon"
|
icon="visibility"
|
||||||
name="visibility"
|
|
||||||
:title="$t('crud.show')"
|
:title="$t('crud.show')"
|
||||||
@click="Modal.switchShowModal(model)"
|
@click="Modal.switchShowModal(model)"
|
||||||
outline
|
outline
|
||||||
@ -97,17 +95,15 @@ const modelModal = ref(Modal.modelModal);
|
|||||||
class="h-fit"
|
class="h-fit"
|
||||||
:to="viewTo({ name: 'edit', params: { id: model.id } })"
|
:to="viewTo({ name: 'edit', params: { id: model.id } })"
|
||||||
>
|
>
|
||||||
<GoogleIcon
|
<IconButton
|
||||||
class="btn-icon"
|
icon="edit"
|
||||||
name="edit"
|
|
||||||
:title="$t('crud.edit')"
|
:title="$t('crud.edit')"
|
||||||
outline
|
outline
|
||||||
/>
|
/>
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
<GoogleIcon
|
<IconButton
|
||||||
v-if="can('destroy')"
|
v-if="can('destroy')"
|
||||||
class="btn-icon"
|
icon="delete"
|
||||||
name="delete"
|
|
||||||
:title="$t('crud.destroy')"
|
:title="$t('crud.destroy')"
|
||||||
@click="Modal.switchDestroyModal(model)"
|
@click="Modal.switchDestroyModal(model)"
|
||||||
outline
|
outline
|
||||||
@ -117,9 +113,8 @@ const modelModal = ref(Modal.modelModal);
|
|||||||
class="h-fit"
|
class="h-fit"
|
||||||
:to="viewTo({ name: 'settings', params: { id: model.id } })"
|
:to="viewTo({ name: 'settings', params: { id: model.id } })"
|
||||||
>
|
>
|
||||||
<GoogleIcon
|
<IconButton
|
||||||
class="btn-icon"
|
icon="settings"
|
||||||
name="settings"
|
|
||||||
:title="$t('setting')"
|
:title="$t('setting')"
|
||||||
/>
|
/>
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
|
|||||||
@ -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>
|
|
||||||
|
|
||||||
@ -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>
|
|
||||||
@ -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
|
|
||||||
}
|
|
||||||
@ -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>
|
|
||||||
@ -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>
|
|
||||||
@ -7,9 +7,9 @@ import { getDateTime } from '@Controllers/DateController.js';
|
|||||||
|
|
||||||
import SearcherHead from '@Holos/Searcher.vue';
|
import SearcherHead from '@Holos/Searcher.vue';
|
||||||
import Table from '@Holos/Table.vue';
|
import Table from '@Holos/Table.vue';
|
||||||
import GoogleIcon from '@Shared/GoogleIcon.vue';
|
|
||||||
import IconButton from '@Holos/Button/Icon.vue';
|
import IconButton from '@Holos/Button/Icon.vue';
|
||||||
import ShowView from '@Holos/Skeleton/Sidebar/Notification/Show.vue';
|
import ShowView from '@Holos/Skeleton/Sidebar/Notification/Show.vue';
|
||||||
|
import GoogleIcon from '@Shared/GoogleIcon.vue';
|
||||||
|
|
||||||
/** Controladores */
|
/** Controladores */
|
||||||
const Modal = new ModalController();
|
const Modal = new ModalController();
|
||||||
@ -41,7 +41,7 @@ onMounted(() => {
|
|||||||
>
|
>
|
||||||
<IconButton
|
<IconButton
|
||||||
icon="refresh"
|
icon="refresh"
|
||||||
:title="$t('notifications.unreadClosed')"
|
:title="$t('refresh')"
|
||||||
@click="searcher.search()"
|
@click="searcher.search()"
|
||||||
/>
|
/>
|
||||||
</SearcherHead>
|
</SearcherHead>
|
||||||
@ -86,9 +86,8 @@ onMounted(() => {
|
|||||||
</td>
|
</td>
|
||||||
<td class="table-item">
|
<td class="table-item">
|
||||||
<div class="table-actions">
|
<div class="table-actions">
|
||||||
<GoogleIcon
|
<IconButton
|
||||||
class="btn-icon"
|
icon="visibility"
|
||||||
name="visibility"
|
|
||||||
:title="$t('crud.show')"
|
:title="$t('crud.show')"
|
||||||
@click="Modal.switchShowModal(model)"
|
@click="Modal.switchShowModal(model)"
|
||||||
outline
|
outline
|
||||||
|
|||||||
@ -3,6 +3,9 @@ import { api } from '@Services/Api';
|
|||||||
|
|
||||||
const permissionsInit = ref(false)
|
const permissionsInit = ref(false)
|
||||||
const allPermissions = ref([])
|
const allPermissions = ref([])
|
||||||
|
const rolesInit = ref(false)
|
||||||
|
const allRoles = ref([])
|
||||||
|
const allRolesIds = ref([])
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Permite consultar si un usuario tiene un permiso especifico
|
* Permite consultar si un usuario tiene un permiso especifico
|
||||||
@ -11,16 +14,26 @@ const hasPermission = (can) => {
|
|||||||
let verifyPermissions = can.split('|');
|
let verifyPermissions = can.split('|');
|
||||||
|
|
||||||
for (let permision in verifyPermissions) {
|
for (let permision in verifyPermissions) {
|
||||||
if(allPermissions.value.length != 0) {
|
if(allPermissions.value.indexOf(verifyPermissions[permision]) != -1) {
|
||||||
if(allPermissions.value.indexOf(verifyPermissions[permision]) != -1) {
|
return true;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const hasRole = (role) => {
|
||||||
|
let verifyRoles = role.split('|');
|
||||||
|
|
||||||
|
for (let role in verifyRoles) {
|
||||||
|
if(allRoles.value.indexOf(verifyRoles[role]) != -1) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
const bootPermissions = () => {
|
const bootPermissions = () => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (!permissionsInit.value) {
|
if (!permissionsInit.value) {
|
||||||
@ -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 = () => {
|
const resetPermissions = () => {
|
||||||
allPermissions.value = [];
|
allPermissions.value = [];
|
||||||
permissionsInit.value = false;
|
permissionsInit.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const resetRoles = () => {
|
||||||
|
allRoles.value = [];
|
||||||
|
rolesInit.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
const loadPermissions = (permissionList = []) => {
|
const loadPermissions = (permissionList = []) => {
|
||||||
|
// Permisos cargados
|
||||||
|
let currentPermissions = [];
|
||||||
|
|
||||||
if (permissionList.length > 0) {
|
if (permissionList.length > 0) {
|
||||||
permissionList.forEach(element => {
|
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;
|
return allPermissions.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getAllRoles = () => {
|
||||||
|
return allRoles.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
const getAllRolesIds = () => {
|
||||||
|
return allRolesIds.value;
|
||||||
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
bootPermissions,
|
bootPermissions,
|
||||||
|
bootRoles,
|
||||||
hasPermission,
|
hasPermission,
|
||||||
|
hasRole,
|
||||||
|
reloadPermissions,
|
||||||
|
reloadRoles,
|
||||||
resetPermissions,
|
resetPermissions,
|
||||||
getAllPermissions
|
resetRoles,
|
||||||
|
getAllPermissions,
|
||||||
|
getAllRoles,
|
||||||
|
getAllRolesIds
|
||||||
};
|
};
|
||||||
@ -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')
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
import { api } from '@Services/Api'
|
import { api } from '@Services/Api'
|
||||||
import { page } from '@Services/Page'
|
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'
|
import { boot as bootAuthUsers, addUser, removeUser } from '@Plugins/AuthUsers'
|
||||||
|
|
||||||
/** Propiedades */
|
/** Propiedades */
|
||||||
@ -25,6 +25,7 @@ const useNotifier = defineStore('notifier', {
|
|||||||
this.subscribeGLobalNotifications();
|
this.subscribeGLobalNotifications();
|
||||||
this.subscribeUserNotifications();
|
this.subscribeUserNotifications();
|
||||||
this.suscribeAuthUsers();
|
this.suscribeAuthUsers();
|
||||||
|
this.suscribeRoles();
|
||||||
this.isStarted = true;
|
this.isStarted = true;
|
||||||
|
|
||||||
this.getUpdates();
|
this.getUpdates();
|
||||||
@ -68,6 +69,18 @@ const useNotifier = defineStore('notifier', {
|
|||||||
Echo.join('online');
|
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
|
// Notificaciones del usuario
|
||||||
subscribeUserNotifications() {
|
subscribeUserNotifications() {
|
||||||
Echo.private(`App.Models.User.${this.user_id}`)
|
Echo.private(`App.Models.User.${this.user_id}`)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user