Merge pull request 'fixed/logo_empresa' (#70) from fixed/logo_empresa into development

Reviewed-on: ADUANASOFT/anexo76#70
This commit is contained in:
2026-01-22 23:30:06 +00:00
13 changed files with 404 additions and 355 deletions

View File

@@ -16,15 +16,27 @@
} = $props();
let items = $state<UnitOfMeasure[]>([]);
let allItems = $state<UnitOfMeasure[]>([]); // Store full dataset
let loading = $state(false);
let searchTerm = $state("");
let page = $state(1);
let totalPages = $state(1);
let searchTimeout: NodeJS.Timeout;
// Derived state for filtering
$effect(() => {
if (!searchTerm) {
items = allItems;
} else {
const lowerTerm = searchTerm.toLowerCase();
items = allItems.filter(item =>
item.code.toLowerCase().includes(lowerTerm) ||
(item.description && item.description.toLowerCase().includes(lowerTerm)) ||
(item.description_en && item.description_en.toLowerCase().includes(lowerTerm))
);
}
});
// Cargar datos al abrir
$effect(() => {
if (open && companyStore.activeCompany) {
if (open && companyStore.activeCompany && allItems.length === 0) {
loadData();
}
});
@@ -34,17 +46,12 @@
loading = true;
try {
const filters = searchTerm ? { code: searchTerm } : {};
// Nota: Si tu backend soporta búsqueda por descripción, úsalo aquí.
// Por ahora asumo búsqueda por 'code' o 'description' según tu filtro backend.
const response = await getUnitsOfMeasure(page, 10, companyStore.activeCompany.id, {
q: searchTerm // Asumiendo que tu backend tiene un filtro genérico 'q' o usa 'code'/'description'
});
// Fetch everything once using the high limit
const response = await getUnitsOfMeasure(1, 1000, companyStore.activeCompany.id, {});
if (response.data) {
items = response.data.items;
totalPages = response.data.pages;
allItems = response.data.items;
items = allItems; // Initialize view
}
} catch (error) {
console.error("Error cargando unidades:", error);
@@ -56,32 +63,13 @@
function handleSearch(e: Event) {
const value = (e.target as HTMLInputElement).value;
searchTerm = value;
page = 1;
clearTimeout(searchTimeout);
searchTimeout = setTimeout(() => {
loadData();
}, 500);
// No network call needed, $effect handles filtering
}
function handleSelect(item: UnitOfMeasure) {
onSelect(item);
open = false;
}
function nextPage() {
if (page < totalPages) {
page++;
loadData();
}
}
function prevPage() {
if (page > 1) {
page--;
loadData();
}
}
</script>
<Dialog.Root bind:open>
@@ -104,7 +92,7 @@
/>
</div>
<div class="rounded-md border h-[300px] overflow-auto relative">
<div class="rounded-md border h-[400px] overflow-auto relative">
{#if loading}
<div class="absolute inset-0 bg-background/50 flex items-center justify-center z-10">
<Loader2 class="h-6 w-6 animate-spin text-primary" />
@@ -146,27 +134,9 @@
</Table.Body>
</Table.Root>
</div>
<div class="flex items-center justify-between">
<span class="text-xs text-muted-foreground">Página {page} de {totalPages}</span>
<div class="flex gap-2">
<Button
variant="outline"
size="sm"
disabled={page === 1 || loading}
onclick={prevPage}
>
Anterior
</Button>
<Button
variant="outline"
size="sm"
disabled={page >= totalPages || loading}
onclick={nextPage}
>
Siguiente
</Button>
</div>
<div class="text-xs text-muted-foreground text-center">
Mostrando {items.length} registros
</div>
</div>
</Dialog.Content>

View File

@@ -10,10 +10,10 @@
const sidebar = useSidebar();
// Derivar la URL del logo
// Derivar la URL del logo usando el endpoint específico
let activeCompanyLogoUrl = $derived(
companyStore.activeCompany?.logo
? getBackendAssetUrl(companyStore.activeCompany.logo)
? getBackendAssetUrl(`v1/a76/company/${companyStore.activeCompany.id}/logo/image?t=${new Date().getTime()}`)
: null
);
@@ -89,7 +89,7 @@
<div class="flex size-6 items-center justify-center rounded-md border overflow-hidden">
{#if company.logo}
<img
src={getBackendAssetUrl(company.logo)}
src={getBackendAssetUrl(`v1/a76/company/${company.id}/logo/image`)}
alt={company.name}
class="size-full rounded object-cover"
/>