This commit updates the module index pages to re-introduce local view toggle buttons, allowing you to temporarily switch between table and card visualizations for the current session. This change is based on your feedback to retain this flexibility alongside the new global default view settings.
Key changes:
- **Module Index Views (e.g., `EmpleadosIndex.vue`):**
- Re-added icon-based toggle buttons for 'Table' and 'Card' views.
- Styled these buttons using Tailwind CSS for a subtle and modern appearance. The active view's button is highlighted using the module's accent color.
- Clicking these buttons updates a local `currentView` ref, which determines the displayed component (table or card).
- This local selection overrides the global default view for the current session only and does not modify the saved default setting in the `useUi` store.
- **Testing:**
- Updated component tests for each module's index view (`AsistenciasIndex.spec.js`, `EmpleadosIndex.spec.js`, etc.).
- Tests now verify:
- Correct rendering and initial styling of the new toggle buttons based on the global default.
- Local view switching functionality upon button clicks.
- Correct update of button styling to reflect the active local view.
- Confirmation that local view changes do not affect the global default view settings in the `useUi` store.
This enhancement ensures that you can set a global default view for each module via settings, while still having the option to quickly toggle the view for your immediate needs without changing your saved preferences.
204 lines
6.3 KiB
Vue
204 lines
6.3 KiB
Vue
<template>
|
|
<div class="asistencias-index-container">
|
|
<header class="page-header">
|
|
<h1>Gestión de Asistencias</h1>
|
|
<button @click="navigateToCreateForm" class="btn-create">
|
|
Registrar Nueva Asistencia
|
|
</button>
|
|
</header>
|
|
|
|
<!-- View Toggle Buttons -->
|
|
<div class="mb-4 flex justify-end space-x-2">
|
|
<button
|
|
@click="currentView = 'table'"
|
|
:class="btnViewClass('table')"
|
|
aria-label="Table View"
|
|
title="Table View"
|
|
>
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 10h16M4 14h16M4 18h16" /></svg>
|
|
</button>
|
|
<button
|
|
@click="currentView = 'card'"
|
|
:class="btnViewClass('card')"
|
|
aria-label="Card View"
|
|
title="Card View"
|
|
>
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2V6zM14 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2V6zM4 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2v-2zM14 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2v-2z" /></svg>
|
|
</button>
|
|
</div>
|
|
|
|
<div v-if="isLoading" class="loading-message">
|
|
Cargando asistencias...
|
|
</div>
|
|
|
|
<div v-else-if="errorLoading" class="error-message-full">
|
|
<p>Ocurrió un error al cargar las asistencias. Por favor, intente de nuevo más tarde.</p>
|
|
<p v-if="errorMessage">Detalle: {{ errorMessage }}</p>
|
|
</div>
|
|
|
|
<div v-else>
|
|
<!-- Vista de Tabla -->
|
|
<div v-if="currentView === 'table'">
|
|
<tabla-asistencias
|
|
:asistencias="asistenciasList"
|
|
@edit="handleEditAsistencia"
|
|
/>
|
|
<div v-if="asistenciasList.length === 0 && !isLoading" class="no-data-message">
|
|
No hay asistencias para mostrar en la vista de tabla.
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Vista de Tarjetas -->
|
|
<div v-if="currentView === 'card'">
|
|
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
|
<CardAsistencia
|
|
v-for="asistencia in asistenciasList"
|
|
:key="asistencia.id"
|
|
:asistencia="asistencia"
|
|
@edit="handleEditAsistencia"
|
|
/>
|
|
</div>
|
|
<div v-if="asistenciasList.length === 0 && !isLoading" class="no-data-message">
|
|
No hay asistencias para mostrar en la vista de tarjetas.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, computed, onMounted } from 'vue';
|
|
import { useAsistenciasStore } from '../../stores/useAsistencias';
|
|
import { useUi } from '../../stores/useUi'; // Import useUi
|
|
import { useRouter } from 'vue-router';
|
|
import TablaAsistencias from '../../components/asistencias/tablaAsistencias.vue';
|
|
import CardAsistencia from '../../components/asistencias/cardAsistencia.vue';
|
|
|
|
const asistenciasStore = useAsistenciasStore();
|
|
const ui = useUi(); // Access the ui store
|
|
const router = useRouter();
|
|
|
|
const isLoading = ref(true);
|
|
const errorLoading = ref(false);
|
|
const errorMessage = ref('');
|
|
|
|
// Initialize currentView from the store's default setting for asistencias
|
|
const currentView = ref(ui.defaultViewAsistencias);
|
|
|
|
const asistenciasList = computed(() => asistenciasStore.asistencias);
|
|
|
|
onMounted(async () => {
|
|
try {
|
|
isLoading.value = true;
|
|
errorLoading.value = false;
|
|
errorMessage.value = '';
|
|
await asistenciasStore.fetchAsistencias();
|
|
} catch (error) {
|
|
console.error("Error fetching asistencias on mount:", error);
|
|
errorLoading.value = true;
|
|
errorMessage.value = error.message || 'Error desconocido al cargar asistencias.';
|
|
} finally {
|
|
isLoading.value = false;
|
|
}
|
|
});
|
|
|
|
const navigateToCreateForm = () => {
|
|
// Assuming route for creating a new asistencia is named 'AsistenciaFormNew'
|
|
router.push({ name: 'asistencias-new' });
|
|
};
|
|
|
|
const handleEditAsistencia = (asistenciaId) => {
|
|
// Assuming route for editing is named 'AsistenciaFormEdit'
|
|
router.push({ name: 'asistencias-edit', params: { id: asistenciaId } });
|
|
};
|
|
|
|
const btnViewClass = (viewType) => {
|
|
const base = 'p-2 rounded-md transition-colors duration-150 ease-in-out';
|
|
if (currentView.value === viewType) {
|
|
return `${base} bg-[var(--accent-color-asistencias)] text-white shadow-lg`;
|
|
}
|
|
return `${base} bg-gray-200 text-gray-700 hover:bg-gray-300 dark:bg-gray-700 dark:text-gray-300 dark:hover:bg-gray-600`;
|
|
};
|
|
|
|
</script>
|
|
|
|
<style scoped>
|
|
.asistencias-index-container {
|
|
padding: 20px;
|
|
max-width: 1200px;
|
|
margin: 0 auto;
|
|
font-family: 'Arial', sans-serif;
|
|
}
|
|
|
|
.page-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-bottom: 25px;
|
|
padding-bottom: 15px;
|
|
border-bottom: 1px solid #dee2e6;
|
|
}
|
|
|
|
.page-header h1 {
|
|
color: var(--accent-color-asistencias); /* Accent color for title */
|
|
font-size: 1.8em;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.btn-create {
|
|
background-color: var(--accent-color-asistencias);
|
|
color: white; /* Assuming accent is dark enough */
|
|
padding: 10px 18px;
|
|
border: none;
|
|
border-radius: 5px;
|
|
font-size: 1em;
|
|
font-weight: 500;
|
|
cursor: pointer;
|
|
transition: background-color 0.2s ease-in-out, box-shadow 0.2s ease, filter 0.2s ease;
|
|
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
|
|
}
|
|
|
|
.btn-create:hover {
|
|
filter: brightness(0.9);
|
|
box-shadow: 0 4px 8px rgba(0,0,0,0.15);
|
|
}
|
|
|
|
.loading-message,
|
|
.error-message-full,
|
|
.no-data-message {
|
|
text-align: center;
|
|
padding: 25px;
|
|
margin-top: 25px;
|
|
border-radius: 8px;
|
|
font-size: 1.1em;
|
|
}
|
|
|
|
.loading-message {
|
|
color: #495057;
|
|
}
|
|
|
|
.error-message-full {
|
|
background-color: #f8d7da;
|
|
color: #721c24;
|
|
border: 1px solid #f5c6cb;
|
|
}
|
|
.error-message-full p {
|
|
margin: 5px 0;
|
|
}
|
|
|
|
.no-data-message {
|
|
background-color: #f8f9fa;
|
|
color: #343a40;
|
|
border: 1px solid #e9ecef;
|
|
}
|
|
|
|
/* Added for view toggle buttons */
|
|
.view-toggle-active-asistencias {
|
|
background-color: var(--accent-color-asistencias);
|
|
/* Assuming --background-color is defined globally or use a fallback like #fff */
|
|
/* For Tailwind, theme('colors.white') could be an option if JIT is enabled and configured */
|
|
box-shadow: 0 0 0 2px var(--background-color, #fff), 0 0 0 4px var(--accent-color-asistencias);
|
|
}
|
|
</style>
|