feat: Reinstate local view toggles in module indexes

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.
This commit is contained in:
google-labs-jules[bot]
2025-05-31 08:05:59 +00:00
parent 32aa41f59f
commit 35a64ff7bf
8 changed files with 407 additions and 7 deletions

View File

@@ -7,7 +7,25 @@
</button> </button>
</header> </header>
<!-- Removed manual view toggle buttons --> <!-- 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"> <div v-if="isLoading" class="loading-message">
Cargando asistencias... Cargando asistencias...
@@ -95,7 +113,13 @@ const handleEditAsistencia = (asistenciaId) => {
router.push({ name: 'asistencias-edit', params: { id: asistenciaId } }); router.push({ name: 'asistencias-edit', params: { id: asistenciaId } });
}; };
// Removed btnClass as manual toggle buttons are removed 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> </script>

View File

@@ -132,4 +132,85 @@ describe('AsistenciasIndex.vue', () => {
expect(wrapper.text()).toContain('No hay asistencias para mostrar'); expect(wrapper.text()).toContain('No hay asistencias para mostrar');
}); });
}) })
describe('Local View Toggle Buttons', () => {
it('renders toggle buttons and reflects initial view from store (table)', async () => {
uiStoreMock.defaultViewAsistencias = 'table';
const wrapper = mountComponent();
await mockFetchAsistencias();
await wrapper.vm.$nextTick();
await wrapper.vm.$nextTick();
const tableViewButton = wrapper.find('button[aria-label="Table View"]');
const cardViewButton = wrapper.find('button[aria-label="Card View"]');
expect(tableViewButton.exists()).toBe(true);
expect(cardViewButton.exists()).toBe(true);
// Check active class based on btnViewClass logic
// Active: bg-[var(--accent-color-asistencias)] text-white
// Inactive: bg-gray-200 text-gray-700
expect(tableViewButton.classes()).toContain('bg-[var(--accent-color-asistencias)]');
expect(cardViewButton.classes()).toContain('bg-gray-200');
});
it('renders toggle buttons and reflects initial view from store (card)', async () => {
uiStoreMock.defaultViewAsistencias = 'card';
const wrapper = mountComponent();
await mockFetchAsistencias();
await wrapper.vm.$nextTick();
await wrapper.vm.$nextTick();
const tableViewButton = wrapper.find('button[aria-label="Table View"]');
const cardViewButton = wrapper.find('button[aria-label="Card View"]');
expect(cardViewButton.classes()).toContain('bg-[var(--accent-color-asistencias)]');
expect(tableViewButton.classes()).toContain('bg-gray-200');
});
it('switches to card view on button click and updates button styles, does not call global store action', async () => {
uiStoreMock.defaultViewAsistencias = 'table';
asistenciasStoreMock.asistencias = [{ id: 1, empleado: 'Test' }];
const wrapper = mountComponent();
await mockFetchAsistencias();
await wrapper.vm.$nextTick();
await wrapper.vm.$nextTick();
const cardViewButton = wrapper.find('button[aria-label="Card View"]');
const tableViewButton = wrapper.find('button[aria-label="Table View"]');
await cardViewButton.trigger('click');
await wrapper.vm.$nextTick();
expect(wrapper.findComponent({ name: 'CardAsistencia' }).exists()).toBe(true);
expect(wrapper.findComponent({ name: 'TablaAsistencias' }).exists()).toBe(false);
expect(cardViewButton.classes()).toContain('bg-[var(--accent-color-asistencias)]');
expect(tableViewButton.classes()).toContain('bg-gray-200');
expect(mockSetDefaultViewAsistencias).not.toHaveBeenCalled();
});
it('switches back to table view on button click and updates button styles, does not call global store action', async () => {
uiStoreMock.defaultViewAsistencias = 'card'; // Start with card view
asistenciasStoreMock.asistencias = [{ id: 1, empleado: 'Test' }];
const wrapper = mountComponent();
await mockFetchAsistencias();
await wrapper.vm.$nextTick();
await wrapper.vm.$nextTick();
// Initially card view is active
const cardViewButton = wrapper.find('button[aria-label="Card View"]');
const tableViewButton = wrapper.find('button[aria-label="Table View"]');
expect(cardViewButton.classes()).toContain('bg-[var(--accent-color-asistencias)]');
await tableViewButton.trigger('click');
await wrapper.vm.$nextTick();
expect(wrapper.findComponent({ name: 'TablaAsistencias' }).exists()).toBe(true);
expect(wrapper.findComponent({ name: 'CardAsistencia' }).exists()).toBe(false);
expect(tableViewButton.classes()).toContain('bg-[var(--accent-color-asistencias)]');
expect(cardViewButton.classes()).toContain('bg-gray-200');
expect(mockSetDefaultViewAsistencias).not.toHaveBeenCalled();
});
});
}) })

View File

@@ -19,7 +19,24 @@
</header> </header>
<!-- selector de vista --> <!-- selector de vista -->
<!-- Removed manual 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>
<!-- contenido --> <!-- contenido -->
<div> <div>
@@ -88,6 +105,13 @@ const employees = empleados;
// --- helpers --- // --- helpers ---
// Removed btnClass as manual toggle buttons are removed // Removed btnClass as manual toggle buttons are removed
const btnViewClass = (viewType: 'card' | 'table') => {
const base = 'p-2 rounded-md transition-colors duration-150 ease-in-out';
if (currentView.value === viewType) {
return `${base} bg-[var(--accent-color-empleados)] 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`;
};
// --- fetch inicial --- // --- fetch inicial ---
const fetchEmployees = async () => { const fetchEmployees = async () => {

View File

@@ -132,4 +132,77 @@ describe('EmpleadosIndex.vue', () => {
expect(wrapper.text()).toContain('No hay empleados para mostrar en la vista de tarjetas.'); expect(wrapper.text()).toContain('No hay empleados para mostrar en la vista de tarjetas.');
}); });
}) })
describe('Local View Toggle Buttons', () => {
it('renders toggle buttons and reflects initial view from store (table)', async () => {
uiStoreMock.defaultViewEmpleados = 'table';
const wrapper = mountComponent();
// Wait for loading and reactivity
await wrapper.vm.$nextTick();
await wrapper.vm.$nextTick();
const tableViewButton = wrapper.find('button[aria-label="Table View"]');
const cardViewButton = wrapper.find('button[aria-label="Card View"]');
expect(tableViewButton.exists()).toBe(true);
expect(cardViewButton.exists()).toBe(true);
expect(tableViewButton.classes()).toContain('bg-[var(--accent-color-empleados)]');
expect(cardViewButton.classes()).toContain('bg-gray-200');
});
it('renders toggle buttons and reflects initial view from store (card)', async () => {
uiStoreMock.defaultViewEmpleados = 'card';
const wrapper = mountComponent();
await wrapper.vm.$nextTick();
await wrapper.vm.$nextTick();
const tableViewButton = wrapper.find('button[aria-label="Table View"]');
const cardViewButton = wrapper.find('button[aria-label="Card View"]');
expect(cardViewButton.classes()).toContain('bg-[var(--accent-color-empleados)]');
expect(tableViewButton.classes()).toContain('bg-gray-200');
});
it('switches to card view on button click and updates button styles, does not call global store action', async () => {
uiStoreMock.defaultViewEmpleados = 'table';
empleadosStoreMock.empleados = [{ id: 1, nombre: 'Test' }];
const wrapper = mountComponent();
await wrapper.vm.$nextTick();
await wrapper.vm.$nextTick();
const cardViewButton = wrapper.find('button[aria-label="Card View"]');
const tableViewButton = wrapper.find('button[aria-label="Table View"]');
await cardViewButton.trigger('click');
await wrapper.vm.$nextTick();
expect(wrapper.findComponent({ name: 'CardEmpleado' }).exists()).toBe(true);
expect(wrapper.findComponent({ name: 'TablaEmpleados' }).exists()).toBe(false);
expect(cardViewButton.classes()).toContain('bg-[var(--accent-color-empleados)]');
expect(tableViewButton.classes()).toContain('bg-gray-200');
expect(mockSetDefaultViewEmpleados).not.toHaveBeenCalled();
});
it('switches back to table view on button click and updates button styles, does not call global store action', async () => {
uiStoreMock.defaultViewEmpleados = 'card'; // Start with card view
empleadosStoreMock.empleados = [{ id: 1, nombre: 'Test' }];
const wrapper = mountComponent();
await wrapper.vm.$nextTick();
await wrapper.vm.$nextTick();
const cardViewButton = wrapper.find('button[aria-label="Card View"]');
const tableViewButton = wrapper.find('button[aria-label="Table View"]');
expect(cardViewButton.classes()).toContain('bg-[var(--accent-color-empleados)]');
await tableViewButton.trigger('click');
await wrapper.vm.$nextTick();
expect(wrapper.findComponent({ name: 'TablaEmpleados' }).exists()).toBe(true);
expect(wrapper.findComponent({ name: 'CardEmpleado' }).exists()).toBe(false);
expect(tableViewButton.classes()).toContain('bg-[var(--accent-color-empleados)]');
expect(cardViewButton.classes()).toContain('bg-gray-200');
expect(mockSetDefaultViewEmpleados).not.toHaveBeenCalled();
});
});
}) })

View File

@@ -7,7 +7,25 @@
</button> </button>
</header> </header>
<!-- Removed manual view toggle buttons --> <!-- 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"> <div v-if="isLoading" class="loading-message">
Cargando planillas... Cargando planillas...
@@ -101,7 +119,13 @@ const handleEditPlanilla = (planillaId) => {
router.push({ name: 'planillas-edit', params: { id: planillaId } }); router.push({ name: 'planillas-edit', params: { id: planillaId } });
}; };
// Removed btnClass as manual toggle buttons are removed 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-planillas)] 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> </script>

View File

@@ -125,4 +125,79 @@ describe('PlanillasIndex.vue', () => {
expect(wrapper.text()).toContain('No hay planillas para mostrar'); expect(wrapper.text()).toContain('No hay planillas para mostrar');
}); });
}) })
describe('Local View Toggle Buttons', () => {
it('renders toggle buttons and reflects initial view from store (table)', async () => {
uiStoreMock.defaultViewPlanillas = 'table';
const wrapper = mountComponent();
await mockFetchPlanillas();
await wrapper.vm.$nextTick();
await wrapper.vm.$nextTick();
const tableViewButton = wrapper.find('button[aria-label="Table View"]');
const cardViewButton = wrapper.find('button[aria-label="Card View"]');
expect(tableViewButton.exists()).toBe(true);
expect(cardViewButton.exists()).toBe(true);
expect(tableViewButton.classes()).toContain('bg-[var(--accent-color-planillas)]');
expect(cardViewButton.classes()).toContain('bg-gray-200');
});
it('renders toggle buttons and reflects initial view from store (card)', async () => {
uiStoreMock.defaultViewPlanillas = 'card';
const wrapper = mountComponent();
await mockFetchPlanillas();
await wrapper.vm.$nextTick();
await wrapper.vm.$nextTick();
const tableViewButton = wrapper.find('button[aria-label="Table View"]');
const cardViewButton = wrapper.find('button[aria-label="Card View"]');
expect(cardViewButton.classes()).toContain('bg-[var(--accent-color-planillas)]');
expect(tableViewButton.classes()).toContain('bg-gray-200');
});
it('switches to card view on button click and updates button styles, does not call global store action', async () => {
uiStoreMock.defaultViewPlanillas = 'table';
planillasStoreMock.planillas = [{ id: 1, periodo: 'Test' }];
const wrapper = mountComponent();
await mockFetchPlanillas();
await wrapper.vm.$nextTick();
await wrapper.vm.$nextTick();
const cardViewButton = wrapper.find('button[aria-label="Card View"]');
const tableViewButton = wrapper.find('button[aria-label="Table View"]');
await cardViewButton.trigger('click');
await wrapper.vm.$nextTick();
expect(wrapper.findComponent({ name: 'CardPlanilla' }).exists()).toBe(true);
expect(wrapper.findComponent({ name: 'TablaPlanillas' }).exists()).toBe(false);
expect(cardViewButton.classes()).toContain('bg-[var(--accent-color-planillas)]');
expect(tableViewButton.classes()).toContain('bg-gray-200');
expect(mockSetDefaultViewPlanillas).not.toHaveBeenCalled();
});
it('switches back to table view on button click and updates button styles, does not call global store action', async () => {
uiStoreMock.defaultViewPlanillas = 'card'; // Start with card view
planillasStoreMock.planillas = [{ id: 1, periodo: 'Test' }];
const wrapper = mountComponent();
await mockFetchPlanillas();
await wrapper.vm.$nextTick();
await wrapper.vm.$nextTick();
const cardViewButton = wrapper.find('button[aria-label="Card View"]');
const tableViewButton = wrapper.find('button[aria-label="Table View"]');
expect(cardViewButton.classes()).toContain('bg-[var(--accent-color-planillas)]');
await tableViewButton.trigger('click');
await wrapper.vm.$nextTick();
expect(wrapper.findComponent({ name: 'TablaPlanillas' }).exists()).toBe(true);
expect(wrapper.findComponent({ name: 'CardPlanilla' }).exists()).toBe(false);
expect(tableViewButton.classes()).toContain('bg-[var(--accent-color-planillas)]');
expect(cardViewButton.classes()).toContain('bg-gray-200');
expect(mockSetDefaultViewPlanillas).not.toHaveBeenCalled();
});
});
}) })

View File

@@ -7,7 +7,25 @@
</button> </button>
</header> </header>
<!-- Removed manual view toggle buttons --> <!-- 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"> <div v-if="isLoading" class="loading-message">
Cargando tareas... Cargando tareas...
@@ -95,7 +113,13 @@ const handleEditTarea = (tareaId) => {
router.push({ name: 'tareas-edit', params: { id: tareaId } }); router.push({ name: 'tareas-edit', params: { id: tareaId } });
}; };
// Removed btnClass as manual toggle buttons are removed 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-tareas)] 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> </script>

View File

@@ -125,4 +125,79 @@ describe('TareasIndex.vue', () => {
expect(wrapper.text()).toContain('No hay tareas para mostrar'); expect(wrapper.text()).toContain('No hay tareas para mostrar');
}); });
}) })
describe('Local View Toggle Buttons', () => {
it('renders toggle buttons and reflects initial view from store (table)', async () => {
uiStoreMock.defaultViewTareas = 'table';
const wrapper = mountComponent();
await mockFetchTareas();
await wrapper.vm.$nextTick();
await wrapper.vm.$nextTick();
const tableViewButton = wrapper.find('button[aria-label="Table View"]');
const cardViewButton = wrapper.find('button[aria-label="Card View"]');
expect(tableViewButton.exists()).toBe(true);
expect(cardViewButton.exists()).toBe(true);
expect(tableViewButton.classes()).toContain('bg-[var(--accent-color-tareas)]');
expect(cardViewButton.classes()).toContain('bg-gray-200');
});
it('renders toggle buttons and reflects initial view from store (card)', async () => {
uiStoreMock.defaultViewTareas = 'card';
const wrapper = mountComponent();
await mockFetchTareas();
await wrapper.vm.$nextTick();
await wrapper.vm.$nextTick();
const tableViewButton = wrapper.find('button[aria-label="Table View"]');
const cardViewButton = wrapper.find('button[aria-label="Card View"]');
expect(cardViewButton.classes()).toContain('bg-[var(--accent-color-tareas)]');
expect(tableViewButton.classes()).toContain('bg-gray-200');
});
it('switches to card view on button click and updates button styles, does not call global store action', async () => {
uiStoreMock.defaultViewTareas = 'table';
tareasStoreMock.tareas = [{ id: 1, titulo: 'Test' }];
const wrapper = mountComponent();
await mockFetchTareas();
await wrapper.vm.$nextTick();
await wrapper.vm.$nextTick();
const cardViewButton = wrapper.find('button[aria-label="Card View"]');
const tableViewButton = wrapper.find('button[aria-label="Table View"]');
await cardViewButton.trigger('click');
await wrapper.vm.$nextTick();
expect(wrapper.findComponent({ name: 'CardTarea' }).exists()).toBe(true);
expect(wrapper.findComponent({ name: 'TablaTareas' }).exists()).toBe(false);
expect(cardViewButton.classes()).toContain('bg-[var(--accent-color-tareas)]');
expect(tableViewButton.classes()).toContain('bg-gray-200');
expect(mockSetDefaultViewTareas).not.toHaveBeenCalled();
});
it('switches back to table view on button click and updates button styles, does not call global store action', async () => {
uiStoreMock.defaultViewTareas = 'card'; // Start with card view
tareasStoreMock.tareas = [{ id: 1, titulo: 'Test' }];
const wrapper = mountComponent();
await mockFetchTareas();
await wrapper.vm.$nextTick();
await wrapper.vm.$nextTick();
const cardViewButton = wrapper.find('button[aria-label="Card View"]');
const tableViewButton = wrapper.find('button[aria-label="Table View"]');
expect(cardViewButton.classes()).toContain('bg-[var(--accent-color-tareas)]');
await tableViewButton.trigger('click');
await wrapper.vm.$nextTick();
expect(wrapper.findComponent({ name: 'TablaTareas' }).exists()).toBe(true);
expect(wrapper.findComponent({ name: 'CardTarea' }).exists()).toBe(false);
expect(tableViewButton.classes()).toContain('bg-[var(--accent-color-tareas)]');
expect(cardViewButton.classes()).toContain('bg-gray-200');
expect(mockSetDefaultViewTareas).not.toHaveBeenCalled();
});
});
}) })