Merge pull request 'feature/filtros-cliente-proveedor' (#311) from feature/filtros-cliente-proveedor into development

Reviewed-on: ADUANASOFT/anexo76#311
This commit is contained in:
2026-04-24 15:35:11 +00:00
3 changed files with 49 additions and 22 deletions

View File

@@ -1,8 +1,9 @@
import { getToken, authStore } from '$lib/auth';
import { get } from 'svelte/store';
const api_url = import.meta.env.VITE_API_URL;
const BASE_URL = `${api_url.endsWith('/') ? api_url : api_url + '/'}v1/core/help-center`;
const api_url = import.meta.env.VITE_API_URL ?? '';
const normalizedApiUrl = api_url ? (api_url.endsWith('/') ? api_url : `${api_url}/`) : '/';
const BASE_URL = `${normalizedApiUrl}v1/core/help-center`;
function getAuthToken(): string | null {
// 1. First try getToken() which checks Keycloak and localStorage

View File

@@ -26,17 +26,18 @@
let items = $state<ClientProvider[]>(data.items || []);
let selectedItem = $state<ClientProvider | null>(null);
let isLoading = $state(false);
let hasMore = $derived(items.length < totalItems);
// Server-side filtering/pagination parameters
let currentPage = $state(data.page || 1);
let pageSize = $state(50);
let totalItems = $state(data.total || 0);
let hasMore = $derived(items.length < totalItems);
// Filter state
let searchName = $state('');
let searchRfc = $state('');
let searchType = $state<string>($page.url.searchParams.get('type') || 'both');
let filterDebounce: ReturnType<typeof setTimeout> | null = null;
// Estado para el diálogo de crear
let showCreateDialog = $state(false);
@@ -75,8 +76,10 @@
try {
const filters: any = {};
if (searchType !== 'both') filters.type = searchType;
if (searchName) filters.name = searchName;
if (searchRfc) filters.rfc = searchRfc;
const trimmedName = searchName.trim();
const trimmedRfc = searchRfc.trim();
if (trimmedName) filters.name = trimmedName;
if (trimmedRfc) filters.rfc = trimmedRfc;
const response = await clientsProvidersApi.list(companyId, pageToLoad, pageSize, filters);
@@ -114,11 +117,6 @@
function handleTypeChange(value: string) {
searchType = value;
loadItems(1);
}
function handleSearch() {
loadItems(1);
}
function selectItem(item: ClientProvider) {
@@ -162,6 +160,26 @@
recargar: () => loadItems(1)
})
);
$effect(() => {
const companyId = companyStore.activeCompany?.id;
if (!browser || !companyId) return;
searchName;
searchRfc;
searchType;
pageSize;
if (filterDebounce) clearTimeout(filterDebounce);
filterDebounce = setTimeout(() => {
selectedItem = null;
loadItems(1);
}, 350);
return () => {
if (filterDebounce) clearTimeout(filterDebounce);
};
});
</script>
<div class="flex flex-col h-[calc(100vh-4rem)] p-4 gap-4 pb-15">
@@ -197,14 +215,13 @@
<h2 class="text-sm font-semibold">Filtros</h2>
<span class="text-xs text-muted-foreground">Busque por nombre, RFC/TAX-ID o tipo</span>
</div>
<div class="grid grid-cols-4 gap-4">
<div class="grid grid-cols-3 gap-4">
<div class="space-y-2">
<Label class="text-xs">Nombre / Razón Social</Label>
<Input
bind:value={searchName}
placeholder="Buscar por nombre..."
class="h-9"
onkeydown={(e) => e.key === 'Enter' && handleSearch()}
/>
</div>
<div class="space-y-2">
@@ -213,7 +230,6 @@
bind:value={searchRfc}
placeholder="RFC / TAX-ID..."
class="h-9"
onkeydown={(e) => e.key === 'Enter' && handleSearch()}
/>
</div>
<div class="space-y-2">
@@ -233,11 +249,6 @@
</Select.Content>
</Select.Root>
</div>
<div class="flex items-end">
<Button variant="secondary" size="sm" class="w-full" onclick={handleSearch}>
Buscar
</Button>
</div>
</div>
</div>
</div>