ADD: Crear componente Dropdown para el sidebar
This commit is contained in:
parent
c6aa67a7f8
commit
38f46cef84
27
src/components/Holos/Button/ButtonRh.vue
Normal file
27
src/components/Holos/Button/ButtonRh.vue
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<script setup>
|
||||||
|
import GoogleIcon from "@Shared/GoogleIcon.vue";
|
||||||
|
defineProps({
|
||||||
|
type: {
|
||||||
|
default: "button",
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
icon: {
|
||||||
|
default: "add",
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
text: {
|
||||||
|
default: "",
|
||||||
|
type: String,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<button
|
||||||
|
:type="type"
|
||||||
|
class="inline-flex items-center gap-3 bg-[#2563eb] hover:bg-[#1e40af] text-white px-4 py-2 rounded-full shadow-md"
|
||||||
|
>
|
||||||
|
<GoogleIcon :name="icon" />
|
||||||
|
<span>{{ text }}</span>
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
78
src/components/Holos/Skeleton/Sidebar/Drop.vue
Normal file
78
src/components/Holos/Skeleton/Sidebar/Drop.vue
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
<script setup>
|
||||||
|
import { ref, computed } from "vue";
|
||||||
|
import { RouterLink, useRoute } from "vue-router";
|
||||||
|
|
||||||
|
import useLeftSidebar from "@Stores/LeftSidebar";
|
||||||
|
import GoogleIcon from "@Shared/GoogleIcon.vue";
|
||||||
|
|
||||||
|
/** Definidores */
|
||||||
|
const leftSidebar = useLeftSidebar();
|
||||||
|
const vroute = useRoute();
|
||||||
|
|
||||||
|
/** Propiedades */
|
||||||
|
const props = defineProps({
|
||||||
|
name: String,
|
||||||
|
icon: String,
|
||||||
|
to: String,
|
||||||
|
active: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
collapsed: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const isCollapsed = ref(props.collapsed);
|
||||||
|
|
||||||
|
const closeSidebar = () => {
|
||||||
|
if (TwScreen.isDevice("phone") || TwScreen.isDevice("tablet")) {
|
||||||
|
leftSidebar.close();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const isActive = computed(() => props.active || props.to === vroute.name);
|
||||||
|
|
||||||
|
const classes = computed(() => {
|
||||||
|
return isActive.value
|
||||||
|
? "flex items-center px-4 py-2 mx-2 my-1 text-white !bg-blue-600 rounded-lg transition-all duration-200 !border-transparent"
|
||||||
|
: "flex items-center px-4 py-2 mx-2 my-1 text-gray-600 hover:bg-gray-100 rounded-lg transition-all duration-200";
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<ul>
|
||||||
|
<li class="hidden md:block">
|
||||||
|
<div class="flex items-center px-2 py-2 rounded">
|
||||||
|
<button
|
||||||
|
class="dropdown-toggle w-full"
|
||||||
|
@click.stop="isCollapsed = !isCollapsed"
|
||||||
|
>
|
||||||
|
<RouterLink
|
||||||
|
:to="$view({ name: props.to })"
|
||||||
|
:class="classes"
|
||||||
|
class="flex items-center justify-between flex-1"
|
||||||
|
@click="closeSidebar"
|
||||||
|
>
|
||||||
|
<div class="flex items-center">
|
||||||
|
<GoogleIcon v-if="icon" :name="icon" class="text-xl mr-2" />
|
||||||
|
<span class="text-sm font-medium">{{ name }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<GoogleIcon
|
||||||
|
:name="isCollapsed ? 'expand_more' : 'expand_less'"
|
||||||
|
class="text-gray-400 text-lg"
|
||||||
|
/>
|
||||||
|
</RouterLink>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<div
|
||||||
|
class="transition-all duration-300 ease-in-out overflow-hidden"
|
||||||
|
:class="{ 'max-h-0': isCollapsed, 'max-h-96': !isCollapsed }"
|
||||||
|
>
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
</ul>
|
||||||
|
</template>
|
||||||
@ -1,19 +1,19 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
/** Propiedades */
|
/** Propiedades */
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
name: String
|
name: String,
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<ul v-if="$slots['default']">
|
<ul v-if="$slots['default']">
|
||||||
<li class="px-5 hidden md:block">
|
<li class="px-5 hidden md:block">
|
||||||
<div class="flex flex-row items-center h-8">
|
<div class="flex flex-row items-center h-8 cursor-pointer">
|
||||||
<div class="text-sm font-light tracking-wide text-gray-400 uppercase">
|
<div class="text-sm font-light tracking-wide text-gray-400 uppercase">
|
||||||
{{name}}
|
{{ name }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<slot />
|
<slot />
|
||||||
</ul>
|
</ul>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import { hasPermission } from '@Plugins/RolePermission';
|
|||||||
import Layout from '@Holos/Layout/App.vue';
|
import Layout from '@Holos/Layout/App.vue';
|
||||||
import Link from '@Holos/Skeleton/Sidebar/Link.vue';
|
import Link from '@Holos/Skeleton/Sidebar/Link.vue';
|
||||||
import Section from '@Holos/Skeleton/Sidebar/Section.vue';
|
import Section from '@Holos/Skeleton/Sidebar/Section.vue';
|
||||||
|
import DropDown from '@Holos/Skeleton/Sidebar/Drop.vue'
|
||||||
|
|
||||||
/** Definidores */
|
/** Definidores */
|
||||||
const loader = useLoader()
|
const loader = useLoader()
|
||||||
@ -30,79 +31,85 @@ onMounted(() => {
|
|||||||
<template #leftSidebar>
|
<template #leftSidebar>
|
||||||
<Section name="Principal">
|
<Section name="Principal">
|
||||||
<Link
|
<Link
|
||||||
icon="grid_view"
|
icon="grid_view"
|
||||||
name="Dashboard"
|
name="Dashboard"
|
||||||
to="admin.dashboard.index"
|
to="admin.dashboard.index"
|
||||||
/>
|
/>
|
||||||
<Link
|
<DropDown
|
||||||
icon="people"
|
icon="people"
|
||||||
name="Empleados"
|
name="Empleados"
|
||||||
to="admin.employees.index"
|
to="admin.employees.index"
|
||||||
/>
|
:collapsed="true"
|
||||||
<Link
|
>
|
||||||
icon="school"
|
<Link
|
||||||
name="Historial Académico"
|
icon="school"
|
||||||
to="admin.academic.index"
|
name="Historial Académico"
|
||||||
/>
|
to="admin.academic.index"
|
||||||
<Link
|
/>
|
||||||
icon="security"
|
<Link
|
||||||
name="Seguridad y Salud"
|
icon="security"
|
||||||
to="admin.security.index"
|
name="Seguridad y Salud"
|
||||||
/>
|
to="admin.security.index"
|
||||||
<Link
|
/>
|
||||||
icon="payments"
|
<Link
|
||||||
name="Nómina"
|
icon="payments"
|
||||||
to="admin.payroll.index"
|
name="Nómina"
|
||||||
/>
|
to="admin.payroll.index"
|
||||||
<Link
|
/>
|
||||||
icon="info"
|
<Link
|
||||||
name="Información Adicional"
|
icon="info"
|
||||||
to="admin.additional.index"
|
name="Información Adicional"
|
||||||
/>
|
to="admin.additional.index"
|
||||||
|
/>
|
||||||
|
</DropDown>
|
||||||
</Section>
|
</Section>
|
||||||
<Section name="Capacitaciones">
|
<Section name="Capacitaciones">
|
||||||
<Link
|
<DropDown
|
||||||
icon="grid_view"
|
|
||||||
name="Solicitud de Cursos"
|
|
||||||
to="admin.courses.request"
|
|
||||||
/>
|
|
||||||
<Link
|
|
||||||
icon="grid_view"
|
icon="grid_view"
|
||||||
name="Cursos"
|
name="Cursos"
|
||||||
to="admin.courses.index"
|
to="admin.courses.index"
|
||||||
/>
|
:collapsed="true"
|
||||||
<Link
|
>
|
||||||
icon="grid_view"
|
<Link
|
||||||
name="Asignación de Cursos"
|
icon="grid_view"
|
||||||
to="admin.courses.assignamment"
|
name="Solicitud de Cursos"
|
||||||
/>
|
to="admin.courses.request"
|
||||||
<Link
|
/>
|
||||||
icon="grid_view"
|
<Link
|
||||||
name="Calendario de Cursos"
|
icon="grid_view"
|
||||||
to="admin.courses.calendar"
|
name="Asignación de Cursos"
|
||||||
/>
|
to="admin.courses.assignamment"
|
||||||
|
/>
|
||||||
|
<Link
|
||||||
|
icon="grid_view"
|
||||||
|
name="Calendario de Cursos"
|
||||||
|
to="admin.courses.calendar"
|
||||||
|
/>
|
||||||
|
</DropDown>
|
||||||
</Section>
|
</Section>
|
||||||
<Section name="Eventos">
|
<Section name="Eventos">
|
||||||
<Link
|
<DropDown
|
||||||
icon="grid_view"
|
icon="grid_view"
|
||||||
name="Dashboard"
|
name="Eventos"
|
||||||
to="admin.events.index"
|
to="admin.events.index"
|
||||||
/>
|
:collapsed="true"
|
||||||
<Link
|
>
|
||||||
icon="grid_view"
|
<Link
|
||||||
name="Asignación de presupuesto"
|
icon="grid_view"
|
||||||
to="admin.events.assignamment"
|
name="Asignación de presupuesto"
|
||||||
/>
|
to="admin.events.assignamment"
|
||||||
<Link
|
/>
|
||||||
icon="grid_view"
|
<Link
|
||||||
name="Justificación de gastos"
|
icon="grid_view"
|
||||||
to="admin.events.justification"
|
name="Justificación de gastos"
|
||||||
/>
|
to="admin.events.justification"
|
||||||
<Link
|
/>
|
||||||
icon="grid_view"
|
<Link
|
||||||
name="Reportes de gastos"
|
icon="grid_view"
|
||||||
to="admin.events.reports"
|
name="Reportes de gastos"
|
||||||
/>
|
to="admin.events.reports"
|
||||||
|
/>
|
||||||
|
</DropDown>
|
||||||
</Section>
|
</Section>
|
||||||
<Section
|
<Section
|
||||||
v-if="hasPermission('users.index')"
|
v-if="hasPermission('users.index')"
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import GoogleIcon from '@Shared/GoogleIcon.vue';
|
import GoogleIcon from '@Shared/GoogleIcon.vue';
|
||||||
|
import Adding from '@Holos/Button/ButtonRh.vue';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -12,13 +13,7 @@ import GoogleIcon from '@Shared/GoogleIcon.vue';
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<button class="inline-flex items-center gap-3 bg-[#2563eb] hover:bg-[#1e40af] text-white px-4 py-2 rounded-full shadow-md">
|
<Adding text="Agregar Registro" />
|
||||||
<GoogleIcon
|
|
||||||
class="text-white text-xl"
|
|
||||||
name="add"
|
|
||||||
/>
|
|
||||||
Agregar Registro
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import GoogleIcon from '@Shared/GoogleIcon.vue';
|
import GoogleIcon from '@Shared/GoogleIcon.vue';
|
||||||
|
import Adding from '@Holos/Button/ButtonRh.vue';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -12,10 +13,7 @@ import GoogleIcon from '@Shared/GoogleIcon.vue';
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<button class="inline-flex items-center gap-3 bg-[#2563eb] hover:bg-[#1e40af] text-white px-4 py-2 rounded-full shadow-md">
|
<Adding text="Nueva Evaluación" />
|
||||||
<GoogleIcon class="text-white text-xl" name="add" />
|
|
||||||
Nueva Evaluación
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import GoogleIcon from '@Shared/GoogleIcon.vue';
|
import GoogleIcon from '@Shared/GoogleIcon.vue';
|
||||||
import Searcher from '@Holos/Searcher.vue';
|
import Searcher from '@Holos/Searcher.vue';
|
||||||
|
import Adding from '@Holos/Button/ButtonRh.vue';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -12,15 +13,8 @@ import Searcher from '@Holos/Searcher.vue';
|
|||||||
<p class="mt-1 text-sm text-gray-500 dark:text-primary-dt/70">Gestión de información general de empleados</p>
|
<p class="mt-1 text-sm text-gray-500 dark:text-primary-dt/70">Gestión de información general de empleados</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex items-center">
|
<div>
|
||||||
<button
|
<Adding text="Nuevo Empleado" />
|
||||||
class="inline-flex items-center gap-2 bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-md shadow-md"
|
|
||||||
>
|
|
||||||
<svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4"/>
|
|
||||||
</svg>
|
|
||||||
Nuevo Empleado
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import GoogleIcon from '@Shared/GoogleIcon.vue';
|
import GoogleIcon from '@Shared/GoogleIcon.vue';
|
||||||
|
import Adding from '@Holos/Button/ButtonRh.vue';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -12,10 +13,7 @@ import GoogleIcon from '@Shared/GoogleIcon.vue';
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<button class="inline-flex items-center gap-3 bg-[#2563eb] hover:bg-[#1e40af] text-white px-4 py-2 rounded-full shadow-md">
|
<Adding text="Procesar Nómina" />
|
||||||
<GoogleIcon class="text-white text-xl" name="add" />
|
|
||||||
Procesar Nómina
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import GoogleIcon from '@Shared/GoogleIcon.vue';
|
import GoogleIcon from '@Shared/GoogleIcon.vue';
|
||||||
|
import Adding from '@Holos/Button/ButtonRh.vue';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -12,10 +13,7 @@ import GoogleIcon from '@Shared/GoogleIcon.vue';
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<button class="inline-flex items-center gap-3 bg-[#2563eb] hover:bg-[#1e40af] text-white px-4 py-2 rounded-full shadow-md">
|
<Adding text="Agregar Información" />
|
||||||
<svg class="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M12 4v16M20 12H4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
|
||||||
Actualizar Información
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@ -95,24 +95,16 @@ const router = createRouter({
|
|||||||
title: 'Inicio',
|
title: 'Inicio',
|
||||||
icon: 'home',
|
icon: 'home',
|
||||||
},
|
},
|
||||||
redirect: '/admin/dashboard',
|
redirect: '/admin/employees',
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: 'dashboard',
|
path: 'dashboard',
|
||||||
name: 'admin.dashboard',
|
name: 'admin.dashboard.index',
|
||||||
component: () => import('@Pages/Dashboard/Admin.vue'),
|
|
||||||
meta: {
|
meta: {
|
||||||
title: 'Dashboard',
|
title: 'Dashboard',
|
||||||
icon: 'grid_view',
|
icon: 'grid_view',
|
||||||
},
|
},
|
||||||
redirect: '/admin/dashboard',
|
component: () => import('@Pages/Dashboard/Admin.vue'),
|
||||||
children: [
|
|
||||||
{
|
|
||||||
path: '',
|
|
||||||
name: 'admin.dashboard.index',
|
|
||||||
component: () => import('@Pages/Dashboard/Admin.vue'),
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'employees',
|
path: 'employees',
|
||||||
@ -127,71 +119,27 @@ const router = createRouter({
|
|||||||
path: '',
|
path: '',
|
||||||
name: 'admin.employees.index',
|
name: 'admin.employees.index',
|
||||||
component: () => import('@Pages/Employees/Index.vue'),
|
component: () => import('@Pages/Employees/Index.vue'),
|
||||||
}
|
},
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'academic',
|
|
||||||
name: 'admin.academic',
|
|
||||||
meta: {
|
|
||||||
title: 'Historial Académico',
|
|
||||||
icon: 'school',
|
|
||||||
},
|
|
||||||
redirect: '/admin/academic',
|
|
||||||
children: [
|
|
||||||
{
|
{
|
||||||
path: '',
|
path: 'academic',
|
||||||
name: 'admin.academic.index',
|
name: 'admin.academic.index',
|
||||||
component: () => import('@Pages/Academic/Index.vue'),
|
component: () => import('@Pages/Academic/Index.vue'),
|
||||||
}
|
},
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'security',
|
|
||||||
name: 'admin.security',
|
|
||||||
meta: {
|
|
||||||
title: 'Seguridad y Salud',
|
|
||||||
icon: 'security',
|
|
||||||
},
|
|
||||||
redirect: '/admin/security',
|
|
||||||
children: [
|
|
||||||
{
|
{
|
||||||
path: '',
|
path: 'security',
|
||||||
name: 'admin.security.index',
|
name: 'admin.security.index',
|
||||||
component: () => import('@Pages/Security/Index.vue'),
|
component: () => import('@Pages/Security/Index.vue'),
|
||||||
}
|
},
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'payroll',
|
|
||||||
name: 'admin.payroll',
|
|
||||||
meta: {
|
|
||||||
title: 'Nómina',
|
|
||||||
icon: 'payments',
|
|
||||||
},
|
|
||||||
redirect: '/admin/payroll',
|
|
||||||
children: [
|
|
||||||
{
|
{
|
||||||
path: '',
|
path: 'payroll',
|
||||||
name: 'admin.payroll.index',
|
name: 'admin.payroll.index',
|
||||||
component: () => import('@Pages/Payroll/Index.vue'),
|
component: () => import('@Pages/Payroll/Index.vue'),
|
||||||
}
|
},
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'additional',
|
|
||||||
name: 'admin.additional',
|
|
||||||
meta: {
|
|
||||||
title: 'Información Adicional',
|
|
||||||
icon: 'info',
|
|
||||||
},
|
|
||||||
redirect: '/admin/additional',
|
|
||||||
children: [
|
|
||||||
{
|
{
|
||||||
path: '',
|
path: 'additional',
|
||||||
name: 'admin.additional.index',
|
name: 'admin.additional.index',
|
||||||
component: () => import('@Pages/Additional/Index.vue'),
|
component: () => import('@Pages/Additional/Index.vue'),
|
||||||
}
|
},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user