diff --git a/frontend/src/app.css b/frontend/src/app.css index 6c344082..627e3836 100644 --- a/frontend/src/app.css +++ b/frontend/src/app.css @@ -121,3 +121,45 @@ @apply bg-background text-foreground overflow-x-hidden; } } + +@layer components { + .catalog-table-shell { + @apply rounded-md border border-border/80 bg-card shadow-sm; + } + + .catalog-table-scroll { + @apply relative w-full flex-1 overflow-auto bg-card; + } + + .catalog-table-header { + @apply sticky top-0 z-20 border-b border-border/80 bg-card/95 shadow-sm backdrop-blur-md; + } + + .catalog-table-head-cell { + @apply whitespace-nowrap text-sm font-semibold text-foreground/90; + } + + .catalog-table-row { + @apply transition-colors hover:bg-accent/35; + } + + .catalog-table-row-selected { + @apply bg-accent/65 text-accent-foreground hover:bg-accent/65; + } + + .catalog-table-sticky-left { + @apply sticky left-0 border-r border-border/70 bg-card shadow-[4px_0_12px_-6px_rgba(0,0,0,0.12)] dark:shadow-[4px_0_12px_-6px_rgba(0,0,0,0.35)]; + } + + .catalog-table-sticky-right { + @apply sticky right-0 border-l border-border/70 bg-card shadow-[-4px_0_12px_-6px_rgba(0,0,0,0.08)] dark:shadow-[-4px_0_12px_-6px_rgba(0,0,0,0.25)]; + } + + .catalog-table-sticky-row-hover { + @apply bg-card group-hover/inv-list:bg-accent/35; + } + + .catalog-table-sticky-row-selected { + @apply bg-accent/65 text-accent-foreground; + } +} diff --git a/frontend/src/lib/api/dashboard/a76/general_catalogs/multi-currency-types.ts b/frontend/src/lib/api/dashboard/a76/general_catalogs/multi-currency-types.ts index fb415397..a565026a 100644 --- a/frontend/src/lib/api/dashboard/a76/general_catalogs/multi-currency-types.ts +++ b/frontend/src/lib/api/dashboard/a76/general_catalogs/multi-currency-types.ts @@ -40,11 +40,14 @@ import type { ApiResponse } from '$lib/api'; export async function getMultiCurrencyTypes( companyId: number, page?: number, - pageSize?: number + pageSize?: number, + filters?: { currency_type_code?: string; country_key?: string } ): Promise> { const params = new URLSearchParams({ company_id: companyId.toString() }); if (page) params.append('page', page.toString()); if (pageSize) params.append('page_size', pageSize.toString()); + if (filters?.currency_type_code) params.append('currency_type_code', filters.currency_type_code); + if (filters?.country_key) params.append('country_key', filters.country_key); return api.get(`/v1/a76/multi-currency-types/?${params.toString()}`); } diff --git a/frontend/src/lib/components/dashboard/common/infinite-data-table.svelte b/frontend/src/lib/components/dashboard/common/infinite-data-table.svelte new file mode 100644 index 00000000..5fbee4e3 --- /dev/null +++ b/frontend/src/lib/components/dashboard/common/infinite-data-table.svelte @@ -0,0 +1,152 @@ + + +
+
+ + + {#each table.getHeaderGroups() as headerGroup (headerGroup.id)} + {@const headerList = headerGroup.headers} + {@const lastHeaderColId = headerList[headerList.length - 1]?.column.id} + + {#each headerList as header (header.id)} + {@const colId = header.column.id} + + {#if !header.isPlaceholder} + + {/if} + + {/each} + + {/each} + + + {#if table.getRowModel().rows.length} + {#each table.getRowModel().rows as row (row.id)} + {@const visibleCells = row.getVisibleCells()} + {@const lastCellColId = visibleCells[visibleCells.length - 1]?.column.id} + + {#each visibleCells as cell (cell.id)} + {@const colId = cell.column.id} + + + + {/each} + + {/each} + {:else} + + + {emptyMessage} + + + {/if} + + {#if hasMore} + + +
+ {#if loading} +
+
+ Cargando más registros... +
+ {:else} +
+ + Desplázate para cargar más + +
+ {/if} +
+
+
+ {/if} +
+
+
+
diff --git a/frontend/src/lib/components/dashboard/general_catalogs/doda/data-table.svelte b/frontend/src/lib/components/dashboard/general_catalogs/doda/data-table.svelte index 7b79bea9..483cc79e 100644 --- a/frontend/src/lib/components/dashboard/general_catalogs/doda/data-table.svelte +++ b/frontend/src/lib/components/dashboard/general_catalogs/doda/data-table.svelte @@ -67,17 +67,18 @@ }); -
+
- - +
+ + {#each table.getHeaderGroups() as headerGroup (headerGroup.id)} {#each headerGroup.headers as header (header.id)} - + {#if !header.isPlaceholder} onRowClick?.(row.original)} - class="cursor-pointer transition-colors {row.getIsSelected() - ? 'bg-gray-300 dark:bg-gray-600' - : 'hover:bg-gray-100 dark:hover:bg-gray-700'}" + class="cursor-pointer {row.getIsSelected() ? 'catalog-table-row-selected' : 'catalog-table-row'}" > {#each row.getVisibleCells() as cell (cell.id)} @@ -106,7 +105,7 @@ {:else} - + No hay resultados. @@ -131,6 +130,7 @@ {/if} - + +
diff --git a/frontend/src/lib/components/dashboard/general_catalogs/inpc/data-table.svelte b/frontend/src/lib/components/dashboard/general_catalogs/inpc/data-table.svelte index 3712b6f3..21ade40a 100644 --- a/frontend/src/lib/components/dashboard/general_catalogs/inpc/data-table.svelte +++ b/frontend/src/lib/components/dashboard/general_catalogs/inpc/data-table.svelte @@ -38,67 +38,69 @@ } -
- - - {#each table.getHeaderGroups() as headerGroup (headerGroup.id)} - - {#each headerGroup.headers as header (header.id)} - - {#if !header.isPlaceholder} - - {/if} - - {/each} - - {/each} - - - {#if table.getRowModel().rows.length} - {#each table.getRowModel().rows as row (row.id)} - - {#each row.getVisibleCells() as cell (cell.id)} - - - +
+
+ + + {#each table.getHeaderGroups() as headerGroup (headerGroup.id)} + + {#each headerGroup.headers as header (header.id)} + + {#if !header.isPlaceholder} + + {/if} + {/each} {/each} - {:else} - - - No hay resultados. - - - {/if} - - -
- -
-
- Total: {totalItems} registros + + + {#if table.getRowModel().rows.length} + {#each table.getRowModel().rows as row (row.id)} + + {#each row.getVisibleCells() as cell (cell.id)} + + + + {/each} + + {/each} + {:else} + + + No hay resultados. + + + {/if} + + +
+ +
+
+ Total: {totalItems} registros +
+ +
- -
diff --git a/frontend/src/lib/components/dashboard/general_catalogs/legends/data-table.svelte b/frontend/src/lib/components/dashboard/general_catalogs/legends/data-table.svelte index 72fb9bf3..e1efce5b 100644 --- a/frontend/src/lib/components/dashboard/general_catalogs/legends/data-table.svelte +++ b/frontend/src/lib/components/dashboard/general_catalogs/legends/data-table.svelte @@ -40,67 +40,69 @@ const currentPage = $derived(Number($page.url.searchParams.get('page') || 1)); -
- - - {#each table.getHeaderGroups() as headerGroup (headerGroup.id)} - - {#each headerGroup.headers as header (header.id)} - - {#if !header.isPlaceholder} - - {/if} - +
+
+ + + {#each table.getHeaderGroups() as headerGroup (headerGroup.id)} + + {#each headerGroup.headers as header (header.id)} + + {#if !header.isPlaceholder} + + {/if} + + {/each} + {/each} - - {/each} - - - {#each table.getRowModel().rows as row (row.id)} - - {#each row.getVisibleCells() as cell (cell.id)} - - - + + + {#each table.getRowModel().rows as row (row.id)} + + {#each row.getVisibleCells() as cell (cell.id)} + + + + {/each} + + {:else} + + + No hay resultados. + + {/each} - - {:else} - - - No hay resultados. - - - {/each} - - -
+ + +
-
-
- Total: {totalItems} registros +
+
+ Total: {totalItems} registros +
+
+ + +
+
-
- - -
-
diff --git a/frontend/src/lib/components/dashboard/general_catalogs/sectors/SectorsList.svelte b/frontend/src/lib/components/dashboard/general_catalogs/sectors/SectorsList.svelte index 78137b1f..dd8be92c 100644 --- a/frontend/src/lib/components/dashboard/general_catalogs/sectors/SectorsList.svelte +++ b/frontend/src/lib/components/dashboard/general_catalogs/sectors/SectorsList.svelte @@ -1,9 +1,8 @@ -
+ +
-

{title}

+

{title}

- + -
-
- - +
+ Listado de Sectores +
+
+ + +
- -
+ +
+
- + - Clave - Descripción - Estatus + Clave + Descripción + Estatus @@ -150,7 +154,7 @@ {:else} {#each sectors as sector} - + {sector.key} {sector.description} @@ -174,15 +178,13 @@ {/if} -
- -
-
- Mostrando {sectors.length} de {total} registros
- -
+ +
Mostrando {sectors.length} de {total} registros
+ + +
diff --git a/frontend/src/lib/components/dashboard/goods/fractions/CanadianFractionList.svelte b/frontend/src/lib/components/dashboard/goods/fractions/CanadianFractionList.svelte index 7513162c..17d936e1 100644 --- a/frontend/src/lib/components/dashboard/goods/fractions/CanadianFractionList.svelte +++ b/frontend/src/lib/components/dashboard/goods/fractions/CanadianFractionList.svelte @@ -1,5 +1,5 @@ -
-
-
-
- -
- - +
+ + +
+ Listado de Fracciones Canadienses +
+
+ + +
+
-
- -
- -
- - - - Fracción - Descripción - País - Unidad - ADV - Acciones - - - - {#if fractions.length === 0 && !loading} - - No se encontraron resultados - - {:else} - {#each fractions as fraction} + + +
+
+ + - {fraction.fraction} - {fraction.description || '-'} - {fraction.country_code} - {fraction.unit_of_measure || '-'} - {fraction.ad_valorem ?? '-'} - -
- - -
-
+ Fracción + Descripción + País + Unidad + ADV + Acciones
- {/each} - {/if} - {#if loading} - - -
- -
-
-
- {/if} - -
-
+ + + {#if fractions.length === 0 && !loading} + + No se encontraron resultados + + {:else} + {#each fractions as fraction} + + {fraction.fraction} + {fraction.description || '-'} + {fraction.country_code} + {fraction.unit_of_measure || '-'} + {fraction.ad_valorem ?? '-'} + +
+ + +
+
+
+ {/each} + {/if} + {#if loading} + + +
+ +
+
+
+ {/if} +
+ +
+
+
+ + - -
+
Mostrando {fractions.length} de {totalItems} registros
- import { onMount, untrack } from 'svelte'; + import { untrack } from 'svelte'; import { getHistoricalFractions, deleteHistoricalFraction, @@ -8,6 +8,7 @@ import * as Table from '$lib/components/ui/table'; import { Input } from '$lib/components/ui/input'; import { Button } from '$lib/components/ui/button'; + import * as Card from '$lib/components/ui/card'; import { Search, Loader2, Plus, Pencil, Trash2 } from 'lucide-svelte'; import { toast } from 'svelte-sonner'; import HistoricalFractionDialog from './HistoricalFractionDialog.svelte'; @@ -169,11 +170,12 @@ let scrollContainer: HTMLDivElement; }); -
+ +
-

{title}

+

{title}

Gestiona las fracciones históricas de la tarifa.

@@ -184,122 +186,100 @@ let scrollContainer: HTMLDivElement;
- -
-
-
- -
- - + + +
+ Listado de Fracciones Históricas +
+
+ + +
-
-
+ + +
+
+ + + + Fracción + Tipo + UM + País + Fecha Pub. + Fecha Fin + IGI + IGE + Acciones + + + + {#if fractions.length === 0 && !loading} + + No se encontraron resultados + + {:else} + {#each fractions as fraction} + + {fraction.historical_fraction} + {fraction.fraction_type || '-'} + {fraction.unit_of_measure_code || '-'} + {fraction.country || '-'} + {fraction.publication_date ? new Date(fraction.publication_date).toLocaleDateString() : '-'} + {fraction.end_date ? new Date(fraction.end_date).toLocaleDateString() : '-'} + {fraction.import_tax_rate ?? '-'} + {fraction.export_tax_rate ?? '-'} + +
+ + +
+
+
+ {/each} + {/if} + {#if loading} + + +
+ +
+
+
+ {/if} +
+
+
+
+
+
+ - -
-
- - - - Fracción - Tipo - UM - País - Fecha Pub. - Fecha Fin - IGI - IGE - Acciones - - - - {#if fractions.length === 0 && !loading} - - No se encontraron resultados - - {:else} - {#each fractions as fraction} - - {fraction.historical_fraction} - {fraction.fraction_type || '-'} - {fraction.unit_of_measure_code || '-'} - {fraction.country || '-'} - {fraction.publication_date - ? new Date(fraction.publication_date).toLocaleDateString() - : '-'} - {fraction.end_date - ? new Date(fraction.end_date).toLocaleDateString() - : '-'} - {fraction.import_tax_rate ?? '-'} - {fraction.export_tax_rate ?? '-'} - -
- - -
-
-
- {/each} - {/if} - {#if loading} - - -
- -
-
-
- {/if} -
-
- - -
-
-
+
Mostrando {fractions.length} de {totalItems} registros
import { Input } from '$lib/components/ui/input'; import { Button } from '$lib/components/ui/button'; - import { Label } from '$lib/components/ui/label'; + import * as Card from '$lib/components/ui/card'; import { Table, TableBody, @@ -17,7 +17,7 @@ type TariffFraction } from '$lib/api/dashboard/a76/general_catalogs/tariff-fractions'; import { companyStore } from '$lib/stores/company.svelte'; - import { onMount, untrack } from 'svelte'; + import { untrack } from 'svelte'; import * as AlertDialog from '$lib/components/ui/alert-dialog'; import TariffFractionFormDialog from './TariffFractionFormDialog.svelte'; import { toast } from 'svelte-sonner'; @@ -43,6 +43,7 @@ let searchTimeout: ReturnType; let observer: IntersectionObserver; let sentinel: HTMLDivElement; + let scrollContainer: HTMLDivElement; // Infinite scroll state let hasMore = $state(true); @@ -121,7 +122,7 @@ handlePageChange(currentPage + 1); } }, - { rootMargin: '100px' } + { root: scrollContainer || null, rootMargin: '100px' } ); if (sentinel) observer.observe(sentinel); @@ -180,108 +181,118 @@ }); -
+
-

{title}

+

{title}

{#if !readOnly} - {/if}
-
-
- - -
-
- -
- - - - Clave - Fracción - Descripción - {#if catalog === 'mex'} - NICO - U.M.T - {:else} - Unidad - {/if} - Adv. Impo - Adv. Expo - {#if !readOnly} - Acciones - {/if} - - - - {#if fractions.length === 0 && !isLoading} - - - No se encontraron resultados - - - {:else} - {#each fractions as fraction} + + +
+ Listado de Fracciones +
+
+ + +
+
+
+
+ +
+
+
+ - {fraction.um_code || fraction.code} - {fraction.fraction} - - {fraction.description} - + Clave + Fracción + Descripción {#if catalog === 'mex'} - {fraction.nico || '-'} - {fraction.umt || '-'} + NICO + U.M.T {:else} - {fraction.umt || '-'} + Unidad {/if} - {fraction.adv_impo || '-'} - {fraction.adv_expo || '-'} + Adv. Impo + Adv. Expo {#if !readOnly} - -
- - -
-
+ Acciones {/if}
- {/each} - {/if} - {#if isLoading} - - -
- -
-
-
- {/if} - -
-
+ + + {#if fractions.length === 0 && !isLoading} + + + No se encontraron resultados + + + {:else} + {#each fractions as fraction} + + {fraction.um_code || fraction.code} + {fraction.fraction} + + {fraction.description} + + {#if catalog === 'mex'} + {fraction.nico || '-'} + {fraction.umt || '-'} + {:else} + {fraction.umt || '-'} + {/if} + {fraction.adv_impo || '-'} + {fraction.adv_expo || '-'} + {#if !readOnly} + +
+ + +
+
+ {/if} +
+ {/each} + {/if} + {#if isLoading} + + +
+ +
+
+
+ {/if} +
+ +
+
+
+ + - -
+
Mostrando {fractions.length} de {totalFractions} registros
diff --git a/frontend/src/lib/components/dashboard/invoices/data-table.svelte b/frontend/src/lib/components/dashboard/invoices/data-table.svelte index f8be72af..3fc036ce 100644 --- a/frontend/src/lib/components/dashboard/invoices/data-table.svelte +++ b/frontend/src/lib/components/dashboard/invoices/data-table.svelte @@ -99,9 +99,13 @@
-
- - +
+
+ + {#each table.getHeaderGroups() as headerGroup (headerGroup.id)} {@const headerList = headerGroup.headers} {@const lastHeaderColId = headerList[headerList.length - 1]?.column.id} @@ -111,9 +115,9 @@ onRowClick && onRowClick(row.original)} > {#each visibleCells as cell (cell.id)} @@ -202,12 +204,12 @@ {/if} - + +
diff --git a/frontend/src/lib/components/dashboard/pedimentos/data-table.svelte b/frontend/src/lib/components/dashboard/pedimentos/data-table.svelte index 3b32dada..eb51c5d2 100644 --- a/frontend/src/lib/components/dashboard/pedimentos/data-table.svelte +++ b/frontend/src/lib/components/dashboard/pedimentos/data-table.svelte @@ -98,18 +98,24 @@
- - +
+ + {#each table.getHeaderGroups() as headerGroup (headerGroup.id)} {#each headerGroup.headers as header (header.id)} - + {@const colId = header.column.id} + {#if !header.isPlaceholder}
diff --git a/frontend/src/lib/components/dashboard/reference_data/code_pedimento_regimens/data-table.svelte b/frontend/src/lib/components/dashboard/reference_data/code_pedimento_regimens/data-table.svelte index 4109783b..1e44175d 100644 --- a/frontend/src/lib/components/dashboard/reference_data/code_pedimento_regimens/data-table.svelte +++ b/frontend/src/lib/components/dashboard/reference_data/code_pedimento_regimens/data-table.svelte @@ -60,7 +60,7 @@
-
+
{#each table.getHeaderGroups() as headerGroup (headerGroup.id)} diff --git a/frontend/src/lib/components/dashboard/reference_data/containers/data-table.svelte b/frontend/src/lib/components/dashboard/reference_data/containers/data-table.svelte index 4109783b..1e44175d 100644 --- a/frontend/src/lib/components/dashboard/reference_data/containers/data-table.svelte +++ b/frontend/src/lib/components/dashboard/reference_data/containers/data-table.svelte @@ -60,7 +60,7 @@
-
+
{#each table.getHeaderGroups() as headerGroup (headerGroup.id)} diff --git a/frontend/src/lib/components/dashboard/reference_data/countries/data-table.svelte b/frontend/src/lib/components/dashboard/reference_data/countries/data-table.svelte index 4109783b..1e44175d 100644 --- a/frontend/src/lib/components/dashboard/reference_data/countries/data-table.svelte +++ b/frontend/src/lib/components/dashboard/reference_data/countries/data-table.svelte @@ -60,7 +60,7 @@
-
+
{#each table.getHeaderGroups() as headerGroup (headerGroup.id)} diff --git a/frontend/src/lib/components/dashboard/reference_data/currency_types/data-table.svelte b/frontend/src/lib/components/dashboard/reference_data/currency_types/data-table.svelte index 4109783b..1e44175d 100644 --- a/frontend/src/lib/components/dashboard/reference_data/currency_types/data-table.svelte +++ b/frontend/src/lib/components/dashboard/reference_data/currency_types/data-table.svelte @@ -60,7 +60,7 @@
-
+
{#each table.getHeaderGroups() as headerGroup (headerGroup.id)} diff --git a/frontend/src/lib/components/dashboard/reference_data/customs_sections/data-table.svelte b/frontend/src/lib/components/dashboard/reference_data/customs_sections/data-table.svelte index c34967ce..0e0ae059 100644 --- a/frontend/src/lib/components/dashboard/reference_data/customs_sections/data-table.svelte +++ b/frontend/src/lib/components/dashboard/reference_data/customs_sections/data-table.svelte @@ -60,7 +60,7 @@
-
+
{#each table.getHeaderGroups() as headerGroup (headerGroup.id)} diff --git a/frontend/src/lib/components/dashboard/reference_data/customs_warehouses/data-table.svelte b/frontend/src/lib/components/dashboard/reference_data/customs_warehouses/data-table.svelte index 4109783b..1e44175d 100644 --- a/frontend/src/lib/components/dashboard/reference_data/customs_warehouses/data-table.svelte +++ b/frontend/src/lib/components/dashboard/reference_data/customs_warehouses/data-table.svelte @@ -60,7 +60,7 @@
-
+
{#each table.getHeaderGroups() as headerGroup (headerGroup.id)} diff --git a/frontend/src/lib/components/dashboard/reference_data/incoterms/data-table.svelte b/frontend/src/lib/components/dashboard/reference_data/incoterms/data-table.svelte index dd73a894..c144ded1 100644 --- a/frontend/src/lib/components/dashboard/reference_data/incoterms/data-table.svelte +++ b/frontend/src/lib/components/dashboard/reference_data/incoterms/data-table.svelte @@ -51,7 +51,7 @@
-
+
{#each table.getHeaderGroups() as headerGroup (headerGroup.id)} diff --git a/frontend/src/lib/components/dashboard/reference_data/invoice_types/data-table.svelte b/frontend/src/lib/components/dashboard/reference_data/invoice_types/data-table.svelte index 4109783b..1e44175d 100644 --- a/frontend/src/lib/components/dashboard/reference_data/invoice_types/data-table.svelte +++ b/frontend/src/lib/components/dashboard/reference_data/invoice_types/data-table.svelte @@ -60,7 +60,7 @@
-
+
{#each table.getHeaderGroups() as headerGroup (headerGroup.id)} diff --git a/frontend/src/lib/components/dashboard/reference_data/material_types/data-table.svelte b/frontend/src/lib/components/dashboard/reference_data/material_types/data-table.svelte index 4109783b..1e44175d 100644 --- a/frontend/src/lib/components/dashboard/reference_data/material_types/data-table.svelte +++ b/frontend/src/lib/components/dashboard/reference_data/material_types/data-table.svelte @@ -60,7 +60,7 @@
-
+
{#each table.getHeaderGroups() as headerGroup (headerGroup.id)} diff --git a/frontend/src/lib/components/dashboard/reference_data/payment_methods/data-table.svelte b/frontend/src/lib/components/dashboard/reference_data/payment_methods/data-table.svelte index 4109783b..1e44175d 100644 --- a/frontend/src/lib/components/dashboard/reference_data/payment_methods/data-table.svelte +++ b/frontend/src/lib/components/dashboard/reference_data/payment_methods/data-table.svelte @@ -60,7 +60,7 @@
-
+
{#each table.getHeaderGroups() as headerGroup (headerGroup.id)} diff --git a/frontend/src/lib/components/dashboard/reference_data/pedimento_codes/data-table.svelte b/frontend/src/lib/components/dashboard/reference_data/pedimento_codes/data-table.svelte index 4109783b..1e44175d 100644 --- a/frontend/src/lib/components/dashboard/reference_data/pedimento_codes/data-table.svelte +++ b/frontend/src/lib/components/dashboard/reference_data/pedimento_codes/data-table.svelte @@ -60,7 +60,7 @@
-
+
{#each table.getHeaderGroups() as headerGroup (headerGroup.id)} diff --git a/frontend/src/lib/components/dashboard/reference_data/pedimento_regimens/data-table.svelte b/frontend/src/lib/components/dashboard/reference_data/pedimento_regimens/data-table.svelte index 4109783b..1e44175d 100644 --- a/frontend/src/lib/components/dashboard/reference_data/pedimento_regimens/data-table.svelte +++ b/frontend/src/lib/components/dashboard/reference_data/pedimento_regimens/data-table.svelte @@ -60,7 +60,7 @@
-
+
{#each table.getHeaderGroups() as headerGroup (headerGroup.id)} diff --git a/frontend/src/lib/components/dashboard/reference_data/sectors/data-table.svelte b/frontend/src/lib/components/dashboard/reference_data/sectors/data-table.svelte index 4109783b..1e44175d 100644 --- a/frontend/src/lib/components/dashboard/reference_data/sectors/data-table.svelte +++ b/frontend/src/lib/components/dashboard/reference_data/sectors/data-table.svelte @@ -60,7 +60,7 @@
-
+
{#each table.getHeaderGroups() as headerGroup (headerGroup.id)} diff --git a/frontend/src/lib/components/dashboard/reference_data/states/data-table.svelte b/frontend/src/lib/components/dashboard/reference_data/states/data-table.svelte index 4109783b..1e44175d 100644 --- a/frontend/src/lib/components/dashboard/reference_data/states/data-table.svelte +++ b/frontend/src/lib/components/dashboard/reference_data/states/data-table.svelte @@ -60,7 +60,7 @@
-
+
{#each table.getHeaderGroups() as headerGroup (headerGroup.id)} diff --git a/frontend/src/lib/components/dashboard/reference_data/transport_modes/data-table.svelte b/frontend/src/lib/components/dashboard/reference_data/transport_modes/data-table.svelte index 4109783b..1e44175d 100644 --- a/frontend/src/lib/components/dashboard/reference_data/transport_modes/data-table.svelte +++ b/frontend/src/lib/components/dashboard/reference_data/transport_modes/data-table.svelte @@ -60,7 +60,7 @@
-
+
{#each table.getHeaderGroups() as headerGroup (headerGroup.id)} diff --git a/frontend/src/lib/components/dashboard/reference_data/transport_types/data-table.svelte b/frontend/src/lib/components/dashboard/reference_data/transport_types/data-table.svelte index 4109783b..1e44175d 100644 --- a/frontend/src/lib/components/dashboard/reference_data/transport_types/data-table.svelte +++ b/frontend/src/lib/components/dashboard/reference_data/transport_types/data-table.svelte @@ -60,7 +60,7 @@
-
+
{#each table.getHeaderGroups() as headerGroup (headerGroup.id)} diff --git a/frontend/src/lib/components/dashboard/reference_data/valuation_methods/data-table.svelte b/frontend/src/lib/components/dashboard/reference_data/valuation_methods/data-table.svelte index 5b63e0a2..17039f91 100644 --- a/frontend/src/lib/components/dashboard/reference_data/valuation_methods/data-table.svelte +++ b/frontend/src/lib/components/dashboard/reference_data/valuation_methods/data-table.svelte @@ -61,7 +61,7 @@
-
+
{#each table.getHeaderGroups() as headerGroup (headerGroup.id)} diff --git a/frontend/src/lib/components/dashboard/seal/data-table.svelte b/frontend/src/lib/components/dashboard/seal/data-table.svelte index 6a70e449..954785f8 100644 --- a/frontend/src/lib/components/dashboard/seal/data-table.svelte +++ b/frontend/src/lib/components/dashboard/seal/data-table.svelte @@ -18,8 +18,8 @@ let { data, columns, loading = false, hasMore = false, loadMore }: Props = $props(); - let scrollContainer: HTMLDivElement; - let observer: IntersectionObserver; + let scrollContainer = $state(); + let loadingTrigger = $state(); let options = $derived>({ get data() { @@ -34,8 +34,7 @@ onMount(() => { if (!loadMore) return; - // Create intersection observer for infinite scroll - observer = new IntersectionObserver( + const observer = new IntersectionObserver( (entries) => { const [entry] = entries; if (entry.isIntersecting && hasMore && !loading && loadMore) { @@ -48,29 +47,24 @@ } ); - // Observe the last row - const lastRow = scrollContainer?.querySelector('tbody tr:last-child'); - if (lastRow) { - observer.observe(lastRow); + if (loadingTrigger) { + observer.observe(loadingTrigger); } return () => { - observer?.disconnect(); + observer.disconnect(); }; }); -
-
+
+
- + {#each table.getHeaderGroups() as headerGroup (headerGroup.id)} {#each headerGroup.headers as header (header.id)} - + {#if !header.isPlaceholder} {#each row.getVisibleCells() as cell (cell.id)} - + {/each} - - {#if loading} + + {#if hasMore} - - Cargando... + +
+ {#if loading} +
+
+ Cargando más registros... +
+ {:else} +
+ + Desplázate para cargar más + +
+ {/if} +
{/if} diff --git a/frontend/src/routes/dashboard/customs_brokers/+page.svelte b/frontend/src/routes/dashboard/customs_brokers/+page.svelte index 611ce839..f54d465c 100644 --- a/frontend/src/routes/dashboard/customs_brokers/+page.svelte +++ b/frontend/src/routes/dashboard/customs_brokers/+page.svelte @@ -187,15 +187,15 @@ const brokerColumns = createBrokerColumns(handleActionSuccess); -
-
-
-

GESTIÓN ADUANAL

-

Administración de Agentes y Secciones Aduanales

+
+
+
+

Gestión Aduanal

+

Administración de Agentes y Secciones Aduanales

- + -
-
+
+

Filtros

@@ -228,7 +228,7 @@
@@ -237,7 +237,7 @@
@@ -246,8 +246,8 @@
-
-
+
+

Listado

@@ -260,7 +260,7 @@
-
+
-
+

Detalles del Agente @@ -407,6 +405,8 @@ + +

import { page } from '$app/stores'; - import DataTable from '$lib/components/dashboard/general_catalogs/classification_concepts/data-table.svelte'; + import InfiniteDataTable from '$lib/components/dashboard/common/infinite-data-table.svelte'; + import * as Card from '$lib/components/ui/card'; import { createColumns } from '$lib/components/dashboard/general_catalogs/classification_concepts/columns'; import CreateDialog from '$lib/components/dashboard/general_catalogs/classification/create-edit-dialog.svelte'; import { Button } from '$lib/components/ui/button'; import { Input } from '$lib/components/ui/input'; - import { Plus } from 'lucide-svelte'; + import { Plus, RefreshCw } from 'lucide-svelte'; import { goto } from '$app/navigation'; import { browser } from '$app/environment'; import { useShortcuts } from '$lib/hooks/use-shortcuts'; import { obtenerAtajosListaClasificacion } from '$lib/config/shortcuts/dashboard/general_catalogs/classification/list'; + import { getClassificationConcepts } from '$lib/api/dashboard/a76/general_catalogs/classification-concepts'; + import { companyStore } from '$lib/stores/company.svelte'; let { data } = $props(); let dialogOpen = $state(false); + let error = $state(data.error || null); // Atajos useShortcuts( @@ -28,17 +32,54 @@ let searchDesc = $state($page.url.searchParams.get('description') || ''); let timeout: ReturnType; - function handleSuccess() { - const url = new URL($page.url); - goto(url, { invalidateAll: true }); - } - const columns = $derived(createColumns(handleSuccess)); - function handleSearch() { + let allItems = $state(data.classifications?.items || []); + let currentPage = $state(data.classifications?.page || 1); + let pageSize = $state(data.classifications?.page_size || 50); + let totalItems = $state(data.classifications?.total || 0); + let loading = $state(false); + let hasMore = $derived(allItems.length < totalItems); + + $effect(() => { + if (data.classifications) { + allItems = data.classifications.items || []; + currentPage = data.classifications.page || 1; + totalItems = data.classifications.total || 0; + pageSize = data.classifications.page_size || pageSize; + } + }); + + async function handleSearch() { if (!browser) return; clearTimeout(timeout); - timeout = setTimeout(() => { + timeout = setTimeout(async () => { + if (!companyStore.activeCompany) return; + loading = true; + error = null; + try { + const filters: Record = {}; + if (searchClassification) filters.classification = searchClassification; + if (searchDesc) filters.description = searchDesc; + + const response = await getClassificationConcepts( + 1, + pageSize, + companyStore.activeCompany.id, + filters + ); + if (response.data) { + allItems = response.data.items; + currentPage = 1; + totalItems = response.data.total; + } + } catch (err) { + error = 'Error aplicando filtros'; + console.error('Error applying filters:', err); + } finally { + loading = false; + } + const url = new URL($page.url); if (searchClassification) url.searchParams.set('classification', searchClassification); else url.searchParams.delete('classification'); @@ -46,47 +87,131 @@ if (searchDesc) url.searchParams.set('description', searchDesc); else url.searchParams.delete('description'); - url.searchParams.set('page', '1'); - goto(url, { keepFocus: true, noScroll: true }); + history.replaceState(history.state, '', url); }, 500); } + + async function loadMore() { + if (loading || !hasMore || !companyStore.activeCompany) return; + loading = true; + error = null; + try { + const filters: Record = {}; + if (searchClassification) filters.classification = searchClassification; + if (searchDesc) filters.description = searchDesc; + + const response = await getClassificationConcepts( + currentPage + 1, + pageSize, + companyStore.activeCompany.id, + filters + ); + if (response.data?.items) { + allItems = [...allItems, ...response.data.items]; + currentPage += 1; + totalItems = response.data.total; + } + } catch (err) { + error = 'Error cargando mas datos'; + console.error('Error loading more classifications:', err); + } finally { + loading = false; + } + } + + async function reloadData() { + if (!companyStore.activeCompany) return; + loading = true; + error = null; + try { + const filters: Record = {}; + if (searchClassification) filters.classification = searchClassification; + if (searchDesc) filters.description = searchDesc; + + const response = await getClassificationConcepts( + 1, + pageSize, + companyStore.activeCompany.id, + filters + ); + if (response.data) { + allItems = response.data.items; + currentPage = 1; + totalItems = response.data.total; + } + } catch (err) { + error = 'Error al recargar datos'; + console.error('Error reloading classifications:', err); + } finally { + loading = false; + } + } + + function handleSuccess() { + reloadData(); + } -
+

Clasificaciones de Conceptos

Gestión del catálogo de clasificaciones de conceptos

- -
- -
-
- -
-
- +
+ +
- + {#if error} +
+ {error} +
+ {/if} + + + +
+ Listado de Clasificaciones +
+ + +
+
+
+ +
+ +
+
+
+ +
+ Mostrando {allItems.length} de {totalItems} registros +
import { page } from '$app/stores'; - import DataTable from '$lib/components/dashboard/general_catalogs/company/data-table.svelte'; + import InfiniteDataTable from '$lib/components/dashboard/common/infinite-data-table.svelte'; import { createColumns } from '$lib/components/dashboard/general_catalogs/company/columns'; + import * as Card from '$lib/components/ui/card'; import { Button } from '$lib/components/ui/button'; import { Input } from '$lib/components/ui/input'; - import { Plus } from 'lucide-svelte'; + import { Plus, RefreshCw } from 'lucide-svelte'; import { goto } from '$app/navigation'; import { browser } from '$app/environment'; import * as m from '$lib/paraglide/messages.js'; import { useShortcuts } from '$lib/hooks/use-shortcuts'; import { obtenerAtajosListaEmpresa } from '$lib/config/shortcuts/dashboard/general_catalogs/company_information/list'; + import { getCompanies } from '$lib/api/dashboard/a76/general_catalogs/company'; let { data } = $props(); @@ -24,16 +26,53 @@ }) ); let dialogOpen = $state(false); + let error = $state(data.error || null); // Filtros let searchName = $state($page.url.searchParams.get('name') || ''); let searchRfc = $state($page.url.searchParams.get('rfc') || ''); let timeout: ReturnType; - function handleSearch() { + let allItems = $state(data.companies?.items || []); + let currentPage = $state(data.companies?.page || 1); + let pageSize = $state(data.companies?.page_size || 50); + let totalItems = $state(data.companies?.total || 0); + let loading = $state(false); + let hasMore = $derived(allItems.length < totalItems); + + $effect(() => { + if (data.companies) { + allItems = data.companies.items || []; + currentPage = data.companies.page || 1; + totalItems = data.companies.total || 0; + pageSize = data.companies.page_size || pageSize; + } + }); + + async function handleSearch() { if (!browser) return; clearTimeout(timeout); - timeout = setTimeout(() => { + timeout = setTimeout(async () => { + loading = true; + error = null; + try { + const filters: Record = {}; + if (searchName) filters.name = searchName; + if (searchRfc) filters.rfc = searchRfc; + + const response = await getCompanies(1, pageSize, filters); + if (response.data) { + allItems = response.data.items; + currentPage = 1; + totalItems = response.data.total; + } + } catch (err) { + error = 'Error aplicando filtros'; + console.error('Error applying filters:', err); + } finally { + loading = false; + } + const url = new URL($page.url); if (searchName) url.searchParams.set('name', searchName); else url.searchParams.delete('name'); @@ -41,44 +80,118 @@ if (searchRfc) url.searchParams.set('rfc', searchRfc); else url.searchParams.delete('rfc'); - url.searchParams.set('page', '1'); - goto(url, { keepFocus: true, noScroll: true }); + history.replaceState(history.state, '', url); }, 500); } + async function loadMore() { + if (loading || !hasMore) return; + loading = true; + error = null; + try { + const filters: Record = {}; + if (searchName) filters.name = searchName; + if (searchRfc) filters.rfc = searchRfc; + + const response = await getCompanies(currentPage + 1, pageSize, filters); + if (response.data?.items) { + allItems = [...allItems, ...response.data.items]; + currentPage += 1; + totalItems = response.data.total; + } + } catch (err) { + error = 'Error cargando mas datos'; + console.error('Error loading more companies:', err); + } finally { + loading = false; + } + } + + async function reloadData() { + loading = true; + error = null; + try { + const filters: Record = {}; + if (searchName) filters.name = searchName; + if (searchRfc) filters.rfc = searchRfc; + + const response = await getCompanies(1, pageSize, filters); + if (response.data) { + allItems = response.data.items; + currentPage = 1; + totalItems = response.data.total; + } + } catch (err) { + error = 'Error al recargar datos'; + console.error('Error reloading companies:', err); + } finally { + loading = false; + } + } + function handleSuccess() { - const url = new URL($page.url); - goto(url, { invalidateAll: true }); + reloadData(); } -
+

Información de Empresas

Gestión de información de empresas

- -
- -
-
- -
-
- +
+ +
-
- + {#if error} +
+ {error} +
+ {/if} + + + +
+ Listado de Empresas +
+ + +
+
+
+ +
+ +
+
+
+ +
+ Mostrando {allItems.length} de {totalItems} registros
diff --git a/frontend/src/routes/dashboard/general_catalogs/concepts/+page.svelte b/frontend/src/routes/dashboard/general_catalogs/concepts/+page.svelte index 63507986..33c48136 100644 --- a/frontend/src/routes/dashboard/general_catalogs/concepts/+page.svelte +++ b/frontend/src/routes/dashboard/general_catalogs/concepts/+page.svelte @@ -1,21 +1,25 @@ -
+

Conceptos

Gestión del catálogo de conceptos

- -
- -
-
- -
-
- +
+ +
-
- + {#if error} +
+ {error} +
+ {/if} + + + +
+ Listado de Conceptos +
+ + +
+
+
+ +
+ +
+
+
+ +
+ Mostrando {allItems.length} de {totalItems} registros
{#if dialogOpen} diff --git a/frontend/src/routes/dashboard/general_catalogs/customs_broker_concepts/+page.svelte b/frontend/src/routes/dashboard/general_catalogs/customs_broker_concepts/+page.svelte index 0f19a0c1..a049231d 100644 --- a/frontend/src/routes/dashboard/general_catalogs/customs_broker_concepts/+page.svelte +++ b/frontend/src/routes/dashboard/general_catalogs/customs_broker_concepts/+page.svelte @@ -1,21 +1,24 @@ -
+

Conceptos de Agente Aduanal

Gestión del catálogo de conceptos de agente aduanal

- -
- -
-
- -
-
- +
+ +
-
- + {#if error} +
+ {error} +
+ {/if} + + + +
+ Listado de Conceptos de Agente Aduanal +
+ + +
+
+
+ +
+ +
+
+
+ +
+ Mostrando {allItems.length} de {totalItems} registros
{#if activeCompanyId} diff --git a/frontend/src/routes/dashboard/general_catalogs/doda/+page.svelte b/frontend/src/routes/dashboard/general_catalogs/doda/+page.svelte index 80684dce..258c3647 100644 --- a/frontend/src/routes/dashboard/general_catalogs/doda/+page.svelte +++ b/frontend/src/routes/dashboard/general_catalogs/doda/+page.svelte @@ -3,7 +3,6 @@ import { goto } from '$app/navigation'; import { browser } from '$app/environment'; import { getDodas, deleteDoda, type Doda } from '$lib/api/dashboard/a76/general_catalogs/doda'; - import * as Card from '$lib/components/ui/card'; import { toast } from 'svelte-sonner'; import { Plus, @@ -16,6 +15,7 @@ LayoutGrid, Printer } from 'lucide-svelte'; + import * as Card from '$lib/components/ui/card'; import * as Select from '$lib/components/ui/select'; import { companyStore } from '$lib/stores/company.svelte'; import DataTable from '$lib/components/dashboard/general_catalogs/doda/data-table.svelte'; @@ -23,7 +23,6 @@ import CreateEditDialog from '$lib/components/dashboard/general_catalogs/doda/create-edit-dialog.svelte'; import { Button } from '$lib/components/ui/button'; import { Input } from '$lib/components/ui/input'; - import { Label } from '$lib/components/ui/label'; import { Separator } from '$lib/components/ui/separator'; import { useShortcuts } from '$lib/hooks/use-shortcuts'; import { obtenerAtajosListaDoda } from '$lib/config/shortcuts/dashboard/general_catalogs/doda/list'; @@ -194,60 +193,45 @@ } -
-
-
-

DODA

+
+
+
+

DODA

Gestiona tus Documentos de Operación Aduanera (DODA)

- +
+ + +
- + -
-
- Filtros Avanzados - Refina tu búsqueda mediante múltiples criterios -
- -
-
- -
-
- +
+ Listado de DODA +
- +
-
- -
- - -
- -
- + (filters.status = v)} > - - {filters.status || 'Todos los estatus'} + + {filters.status || 'Estatus'} Todos @@ -257,21 +241,17 @@ ELIMINADO -
- -
- (filters.operation_type = v)} > - + {filters.operation_type === 'I' ? 'Importación' : filters.operation_type === 'E' ? 'Exportación' - : 'Todas'} + : 'Operación'} Todas @@ -279,38 +259,35 @@ E - Exportación +
+ + +
+ +
- - -
-
- Listado de DODAs - - Mostrando {allItems.length} de {totalItems} registros - -
- -
-
- - - -
+
+ Mostrando {allItems.length} de {totalItems} registros + + Filtros activos: {Object.values(filters).filter((value) => value !== '').length} +
+ +
-
- - {#if dialogOpen} {/if} diff --git a/frontend/src/routes/dashboard/general_catalogs/doda/edit/[[id]]/+page.svelte b/frontend/src/routes/dashboard/general_catalogs/doda/edit/[[id]]/+page.svelte index 67e241a0..db7208ec 100644 --- a/frontend/src/routes/dashboard/general_catalogs/doda/edit/[[id]]/+page.svelte +++ b/frontend/src/routes/dashboard/general_catalogs/doda/edit/[[id]]/+page.svelte @@ -262,7 +262,7 @@ > -

{title}

+

{title}

Catálogos Generales / Doda

diff --git a/frontend/src/routes/dashboard/general_catalogs/drivers/+page.svelte b/frontend/src/routes/dashboard/general_catalogs/drivers/+page.svelte index 03a29c1c..0f089351 100644 --- a/frontend/src/routes/dashboard/general_catalogs/drivers/+page.svelte +++ b/frontend/src/routes/dashboard/general_catalogs/drivers/+page.svelte @@ -1,11 +1,12 @@ -
+
-

Conductores

+

Conductores

Gestión del catálogo de conductores

- +
-
- - -
+ +
Listado de Conductores
+ {#if loading && data.length === 0}
Cargando conductores...
{:else}
{/if}
+
- {#if loading && data.length === 0} -
- Cargando conductores... -
- {:else} - - {/if} +
Mostrando {data.length} de {totalItems} registros
diff --git a/frontend/src/routes/dashboard/general_catalogs/electronic_notices/+page.svelte b/frontend/src/routes/dashboard/general_catalogs/electronic_notices/+page.svelte index 3c3fa9f7..7aa48435 100644 --- a/frontend/src/routes/dashboard/general_catalogs/electronic_notices/+page.svelte +++ b/frontend/src/routes/dashboard/general_catalogs/electronic_notices/+page.svelte @@ -2,17 +2,21 @@ import { page } from '$app/stores'; import { goto } from '$app/navigation'; import { browser } from '$app/environment'; - import DataTable from '$lib/components/dashboard/general_catalogs/electronic_notices/data-table.svelte'; + import InfiniteDataTable from '$lib/components/dashboard/common/infinite-data-table.svelte'; import { createColumns } from '$lib/components/dashboard/general_catalogs/electronic_notices/columns.js'; import CreateEditDialog from '$lib/components/dashboard/general_catalogs/electronic_notices/create-edit-dialog.svelte'; + import * as Card from '$lib/components/ui/card'; import { Button } from '$lib/components/ui/button'; import { Input } from '$lib/components/ui/input'; - import { Plus } from 'lucide-svelte'; + import { Plus, RefreshCw } from 'lucide-svelte'; import { useShortcuts } from '$lib/hooks/use-shortcuts'; import { obtenerAtajosListaAvisosElectrónicos } from '$lib/config/shortcuts/dashboard/general_catalogs/electronic_notices/list'; + import { getElectronicNotices } from '$lib/api/dashboard/a76/general_catalogs/electronic-notices'; + import { companyStore } from '$lib/stores/company.svelte'; let { data } = $props(); let dialogOpen = $state(false); + let error = $state(data.error || null); // Atajos useShortcuts( @@ -28,10 +32,52 @@ let searchPedimento = $state($page.url.searchParams.get('pedimento') || ''); let timeout: ReturnType; - function handleSearch() { + let allItems = $state(data.notices?.items || []); + let currentPage = $state(data.notices?.page || 1); + let pageSize = $state(data.notices?.page_size || 50); + let totalItems = $state(data.notices?.total || 0); + let loading = $state(false); + let hasMore = $derived(allItems.length < totalItems); + + $effect(() => { + if (data.notices) { + allItems = data.notices.items || []; + currentPage = data.notices.page || 1; + totalItems = data.notices.total || 0; + pageSize = data.notices.page_size || pageSize; + } + }); + + async function handleSearch() { if (!browser) return; clearTimeout(timeout); - timeout = setTimeout(() => { + timeout = setTimeout(async () => { + if (!companyStore.activeCompany) return; + loading = true; + error = null; + try { + const filters: Record = {}; + if (searchNotice) filters.notice_number = searchNotice; + if (searchPedimento) filters.pedimento = searchPedimento; + + const response = await getElectronicNotices( + 1, + pageSize, + filters, + companyStore.activeCompany.id + ); + if (response?.items) { + allItems = response.items; + currentPage = 1; + totalItems = response.total; + } + } catch (err) { + error = 'Error aplicando filtros'; + console.error('Error applying filters:', err); + } finally { + loading = false; + } + const url = new URL($page.url); if (searchNotice) url.searchParams.set('notice_number', searchNotice); else url.searchParams.delete('notice_number'); @@ -39,54 +85,92 @@ if (searchPedimento) url.searchParams.set('pedimento', searchPedimento); else url.searchParams.delete('pedimento'); - url.searchParams.set('page', '1'); - goto(url, { keepFocus: true, noScroll: true }); + history.replaceState(history.state, '', url); }, 500); } + async function loadMore() { + if (loading || !hasMore || !companyStore.activeCompany) return; + loading = true; + error = null; + try { + const filters: Record = {}; + if (searchNotice) filters.notice_number = searchNotice; + if (searchPedimento) filters.pedimento = searchPedimento; + + const response = await getElectronicNotices( + currentPage + 1, + pageSize, + filters, + companyStore.activeCompany.id + ); + if (response?.items) { + allItems = [...allItems, ...response.items]; + currentPage += 1; + totalItems = response.total; + } + } catch (err) { + error = 'Error cargando mas datos'; + console.error('Error loading more electronic notices:', err); + } finally { + loading = false; + } + } + + async function reloadData() { + if (!companyStore.activeCompany) return; + loading = true; + error = null; + try { + const filters: Record = {}; + if (searchNotice) filters.notice_number = searchNotice; + if (searchPedimento) filters.pedimento = searchPedimento; + + const response = await getElectronicNotices( + 1, + pageSize, + filters, + companyStore.activeCompany.id + ); + if (response?.items) { + allItems = response.items; + currentPage = 1; + totalItems = response.total; + } + } catch (err) { + error = 'Error al recargar datos'; + console.error('Error reloading electronic notices:', err); + } finally { + loading = false; + } + } + function handleSuccess() { - const url = new URL($page.url); - goto(url, { invalidateAll: true }); + reloadData(); } -
+

Avisos Electrónicos

Gestión del catálogo de avisos electrónicos

- +
-
-
- + {#if error} +
+ {error}
-
- -
-
+ {/if} -
- -
+ +
Listado de Avisos
+
+
+ +
Mostrando {allItems.length} de {totalItems} registros
diff --git a/frontend/src/routes/dashboard/general_catalogs/equivalencies/+page.svelte b/frontend/src/routes/dashboard/general_catalogs/equivalencies/+page.svelte index d86f780d..51a76f07 100644 --- a/frontend/src/routes/dashboard/general_catalogs/equivalencies/+page.svelte +++ b/frontend/src/routes/dashboard/general_catalogs/equivalencies/+page.svelte @@ -4,16 +4,20 @@ import { browser } from '$app/environment'; import type { Equivalency } from '$lib/api/dashboard/a76/general_catalogs/equivalencies'; import { createCatalogColumns } from '$lib/components/dashboard/general_catalogs/equivalencies/catalog-columns'; - import DataTable from '$lib/components/dashboard/general_catalogs/equivalencies/data-table.svelte'; + import InfiniteDataTable from '$lib/components/dashboard/common/infinite-data-table.svelte'; + import * as Card from '$lib/components/ui/card'; import { Button } from '$lib/components/ui/button'; import { Input } from '$lib/components/ui/input'; - import { Plus } from 'lucide-svelte'; + import { Plus, RefreshCw } from 'lucide-svelte'; import { useShortcuts } from '$lib/hooks/use-shortcuts'; import { obtenerAtajosListaEquivalencias } from '$lib/config/shortcuts/dashboard/general_catalogs/equivalencies/list'; import DataEquivalenciesDialog from '$lib/components/dashboard/general_catalogs/equivalencies/data-equivalencies-dialog.svelte'; import type { PageData } from './$types'; + import { getEquivalencies } from '$lib/api/dashboard/a76/general_catalogs/equivalencies'; + import { companyStore } from '$lib/stores/company.svelte'; let { data }: { data: PageData } = $props(); + let error = $state(data.error || null); let dataDialogOpen = $state(false); let selectedEquivalency = $state(null); @@ -36,22 +40,115 @@ let searchFrom = $state($page.url.searchParams.get('from_unit_code') || ''); let timeout: ReturnType; - function handleSearch() { + let allItems = $state(data.equivalencies?.items || []); + let currentPage = $state(data.equivalencies?.page || 1); + let pageSize = $state(data.equivalencies?.page_size || 50); + let totalItems = $state(data.equivalencies?.total || 0); + let loading = $state(false); + let hasMore = $derived(allItems.length < totalItems); + + $effect(() => { + if (data.equivalencies) { + allItems = data.equivalencies.items || []; + currentPage = data.equivalencies.page || 1; + totalItems = data.equivalencies.total || 0; + pageSize = data.equivalencies.page_size || pageSize; + } + }); + + async function handleSearch() { if (!browser) return; clearTimeout(timeout); - timeout = setTimeout(() => { + timeout = setTimeout(async () => { + if (!companyStore.activeCompany) return; + loading = true; + error = null; + try { + const filters: Record = {}; + if (searchFrom) filters.from_unit_code = searchFrom; + + const response = await getEquivalencies( + 1, + pageSize, + companyStore.activeCompany.id, + filters + ); + if (response.data) { + allItems = response.data.items; + currentPage = 1; + totalItems = response.data.total; + } + } catch (err) { + error = 'Error aplicando filtros'; + console.error('Error applying filters:', err); + } finally { + loading = false; + } + const url = new URL($page.url); if (searchFrom) url.searchParams.set('from_unit_code', searchFrom); else url.searchParams.delete('from_unit_code'); - url.searchParams.set('page', '1'); - goto(url, { keepFocus: true, noScroll: true }); + history.replaceState(history.state, '', url); }, 500); } + async function loadMore() { + if (loading || !hasMore || !companyStore.activeCompany) return; + loading = true; + error = null; + try { + const filters: Record = {}; + if (searchFrom) filters.from_unit_code = searchFrom; + + const response = await getEquivalencies( + currentPage + 1, + pageSize, + companyStore.activeCompany.id, + filters + ); + if (response.data?.items) { + allItems = [...allItems, ...response.data.items]; + currentPage += 1; + totalItems = response.data.total; + } + } catch (err) { + error = 'Error cargando mas datos'; + console.error('Error loading more equivalencies:', err); + } finally { + loading = false; + } + } + + async function reloadData() { + if (!companyStore.activeCompany) return; + loading = true; + error = null; + try { + const filters: Record = {}; + if (searchFrom) filters.from_unit_code = searchFrom; + + const response = await getEquivalencies( + 1, + pageSize, + companyStore.activeCompany.id, + filters + ); + if (response.data) { + allItems = response.data.items; + currentPage = 1; + totalItems = response.data.total; + } + } catch (err) { + error = 'Error al recargar datos'; + console.error('Error reloading equivalencies:', err); + } finally { + loading = false; + } + } + function handleSuccess() { - const url = new URL($page.url); - goto(url, { invalidateAll: true }); + reloadData(); } function handleOpenInsertItems(equivalency: Equivalency) { @@ -67,13 +164,13 @@ } -
+

Equivalencias

Catálogo de equivalencias

- +
-
-
- + {#if error} +
+ {error}
-
+ {/if} - + +
Listado de Equivalencias
+
+
+ +
Mostrando {allItems.length} de {totalItems} registros
(data.error || null); // Atajos useShortcuts( @@ -29,10 +33,52 @@ let searchDesc = $state($page.url.searchParams.get('description') || ''); let timeout: ReturnType; - function handleSearch() { + let allItems = $state(data.errors?.items || []); + let currentPage = $state(data.errors?.page || 1); + let pageSize = $state(data.errors?.page_size || 50); + let totalItems = $state(data.errors?.total || 0); + let loading = $state(false); + let hasMore = $derived(allItems.length < totalItems); + + $effect(() => { + if (data.errors) { + allItems = data.errors.items || []; + currentPage = data.errors.page || 1; + totalItems = data.errors.total || 0; + pageSize = data.errors.page_size || pageSize; + } + }); + + async function handleSearch() { if (!browser) return; clearTimeout(timeout); - timeout = setTimeout(() => { + timeout = setTimeout(async () => { + if (!companyStore.activeCompany) return; + loading = true; + error = null; + try { + const filters: Record = {}; + if (searchCode) filters.code = searchCode; + if (searchDesc) filters.description = searchDesc; + + const response = await getErrorCatalogs( + companyStore.activeCompany.id, + 1, + pageSize, + filters + ); + if (response?.items) { + allItems = response.items; + currentPage = 1; + totalItems = response.total; + } + } catch (err) { + error = 'Error aplicando filtros'; + console.error('Error applying filters:', err); + } finally { + loading = false; + } + const url = new URL($page.url); if (searchCode) url.searchParams.set('code', searchCode); else url.searchParams.delete('code'); @@ -40,50 +86,92 @@ if (searchDesc) url.searchParams.set('description', searchDesc); else url.searchParams.delete('description'); - url.searchParams.set('page', '1'); - goto(url, { keepFocus: true, noScroll: true }); + history.replaceState(history.state, '', url); }, 500); } + async function loadMore() { + if (loading || !hasMore || !companyStore.activeCompany) return; + loading = true; + error = null; + try { + const filters: Record = {}; + if (searchCode) filters.code = searchCode; + if (searchDesc) filters.description = searchDesc; + + const response = await getErrorCatalogs( + companyStore.activeCompany.id, + currentPage + 1, + pageSize, + filters + ); + if (response?.items) { + allItems = [...allItems, ...response.items]; + currentPage += 1; + totalItems = response.total; + } + } catch (err) { + error = 'Error cargando mas datos'; + console.error('Error loading more error catalogs:', err); + } finally { + loading = false; + } + } + + async function reloadData() { + if (!companyStore.activeCompany) return; + loading = true; + error = null; + try { + const filters: Record = {}; + if (searchCode) filters.code = searchCode; + if (searchDesc) filters.description = searchDesc; + + const response = await getErrorCatalogs( + companyStore.activeCompany.id, + 1, + pageSize, + filters + ); + if (response?.items) { + allItems = response.items; + currentPage = 1; + totalItems = response.total; + } + } catch (err) { + error = 'Error al recargar datos'; + console.error('Error reloading error catalogs:', err); + } finally { + loading = false; + } + } + function handleSuccess() { - const url = new URL($page.url); - goto(url, { invalidateAll: true }); + reloadData(); } -
+

Errores de Facturación

Gestión del catálogo de errores de facturación

- +
-
-
- + {#if error} +
+ {error}
-
- -
-
+ {/if} -
- -
+ +
Listado de Errores
+
+
+ +
Mostrando {allItems.length} de {totalItems} registros
diff --git a/frontend/src/routes/dashboard/general_catalogs/exchange-rate/+page.svelte b/frontend/src/routes/dashboard/general_catalogs/exchange-rate/+page.svelte index d2c20235..a68435cb 100644 --- a/frontend/src/routes/dashboard/general_catalogs/exchange-rate/+page.svelte +++ b/frontend/src/routes/dashboard/general_catalogs/exchange-rate/+page.svelte @@ -4,17 +4,21 @@ import { browser } from '$app/environment'; import { createColumns } from '$lib/components/dashboard/exchange_rate/columns'; import CreateEditDialog from '$lib/components/dashboard/exchange_rate/create-edit-dialog.svelte'; - import DataTable from '$lib/components/dashboard/exchange_rate/data-table.svelte'; + import InfiniteDataTable from '$lib/components/dashboard/common/infinite-data-table.svelte'; + import * as Card from '$lib/components/ui/card'; import { Button } from '$lib/components/ui/button'; import { Input } from '$lib/components/ui/input'; - import { Plus } from 'lucide-svelte'; + import { Plus, RefreshCw } from 'lucide-svelte'; import { useShortcuts } from '$lib/hooks/use-shortcuts'; import { obtenerAtajosListaTiposCambio } from '$lib/config/shortcuts/dashboard/general_catalogs/exchange_rate/list'; import type { PageData } from './$types'; + import { getExchangeRates } from '$lib/api/dashboard/a76/general_catalogs/exchange-rate'; + import { companyStore } from '$lib/stores/company.svelte'; let { data }: { data: PageData } = $props(); let createDialogOpen = $state(false); + let error = $state(data.error || null); // Atajos useShortcuts( @@ -36,55 +40,127 @@ let searchCurrency = $state($page.url.searchParams.get('local_currency') || ''); let timeout: ReturnType; - function handleSearch() { + let allItems = $state(data.exchange_rates?.items || []); + let currentPage = $state(data.exchange_rates?.page || 1); + let pageSize = $state(data.exchange_rates?.page_size || 50); + let totalItems = $state(data.exchange_rates?.total || 0); + let loading = $state(false); + let hasMore = $derived(allItems.length < totalItems); + + $effect(() => { + if (data.exchange_rates) { + allItems = data.exchange_rates.items || []; + currentPage = data.exchange_rates.page || 1; + totalItems = data.exchange_rates.total || 0; + pageSize = data.exchange_rates.page_size || pageSize; + } + }); + + async function handleSearch() { if (!browser) return; clearTimeout(timeout); - timeout = setTimeout(() => { + timeout = setTimeout(async () => { + if (!companyStore.activeCompany) return; + loading = true; + error = null; + try { + const response = await getExchangeRates(companyStore.activeCompany.id, { + local_currency: searchCurrency || undefined, + page: 1, + page_size: pageSize + }); + if (response.data) { + allItems = response.data.items; + currentPage = response.data.page || 1; + totalItems = response.data.total || 0; + } + } catch (err) { + error = 'Error aplicando filtros'; + console.error('Error applying filters:', err); + } finally { + loading = false; + } + const url = new URL($page.url); if (searchCurrency) url.searchParams.set('local_currency', searchCurrency); else url.searchParams.delete('local_currency'); - url.searchParams.set('page', '1'); - goto(url, { keepFocus: true, noScroll: true }); + history.replaceState(history.state, '', url); }, 500); } + async function loadMore() { + if (loading || !hasMore || !companyStore.activeCompany) return; + loading = true; + error = null; + try { + const response = await getExchangeRates(companyStore.activeCompany.id, { + local_currency: searchCurrency || undefined, + page: currentPage + 1, + page_size: pageSize + }); + if (response.data?.items) { + allItems = [...allItems, ...response.data.items]; + currentPage += 1; + totalItems = response.data.total || 0; + } + } catch (err) { + error = 'Error cargando mas datos'; + console.error('Error loading more exchange rates:', err); + } finally { + loading = false; + } + } + + async function reloadData() { + if (!companyStore.activeCompany) return; + loading = true; + error = null; + try { + const response = await getExchangeRates(companyStore.activeCompany.id, { + local_currency: searchCurrency || undefined, + page: 1, + page_size: pageSize + }); + if (response.data) { + allItems = response.data.items; + currentPage = response.data.page || 1; + totalItems = response.data.total || 0; + } + } catch (err) { + error = 'Error al recargar datos'; + console.error('Error reloading exchange rates:', err); + } finally { + loading = false; + } + } + function handleSuccess() { - const url = new URL($page.url); - goto(url, { invalidateAll: true }); + reloadData(); } -
+

Tipos de Cambio

Catálogo de tipos de cambio

- +
-
-
- + {#if error} +
+ {error}
-
+ {/if} -
- -
+ +
Listado de Tipos de Cambio
+
+
+ +
Mostrando {allItems.length} de {totalItems} registros
diff --git a/frontend/src/routes/dashboard/general_catalogs/identifiers/+page.svelte b/frontend/src/routes/dashboard/general_catalogs/identifiers/+page.svelte index 31be43a1..d986d669 100644 --- a/frontend/src/routes/dashboard/general_catalogs/identifiers/+page.svelte +++ b/frontend/src/routes/dashboard/general_catalogs/identifiers/+page.svelte @@ -4,17 +4,21 @@ import { browser } from '$app/environment'; import { createColumns } from '$lib/components/dashboard/general_catalogs/identifiers/columns'; import CreateEditDialog from '$lib/components/dashboard/general_catalogs/identifiers/create-edit-dialog.svelte'; - import DataTable from '$lib/components/dashboard/general_catalogs/identifiers/data-table.svelte'; + import InfiniteDataTable from '$lib/components/dashboard/common/infinite-data-table.svelte'; + import * as Card from '$lib/components/ui/card'; import { Button } from '$lib/components/ui/button'; import { Input } from '$lib/components/ui/input'; - import { Plus } from 'lucide-svelte'; + import { Plus, RefreshCw } from 'lucide-svelte'; import type { PageData } from './$types'; import { useShortcuts } from '$lib/hooks/use-shortcuts'; import { obtenerAtajosListaIdentificadores } from '$lib/config/shortcuts/dashboard/general_catalogs/identifiers/list'; + import { getIdentifiers } from '$lib/api/dashboard/a76/general_catalogs/identifiers'; + import { companyStore } from '$lib/stores/company.svelte'; let { data }: { data: PageData } = $props(); let createDialogOpen = $state(false); + let error = $state(data.error || null); // Atajos useShortcuts( @@ -30,10 +34,47 @@ let searchDesc = $state($page.url.searchParams.get('description') || ''); let timeout: ReturnType; - function handleSearch() { + let allItems = $state(data.identifiers?.items || []); + let currentPage = $state(data.identifiers?.page || 1); + let pageSize = $state(data.identifiers?.page_size || 50); + let totalItems = $state(data.identifiers?.total || 0); + let loading = $state(false); + let hasMore = $derived(allItems.length < totalItems); + + $effect(() => { + if (data.identifiers) { + allItems = data.identifiers.items || []; + currentPage = data.identifiers.page || 1; + totalItems = data.identifiers.total || 0; + pageSize = data.identifiers.page_size || pageSize; + } + }); + + async function handleSearch() { if (!browser) return; clearTimeout(timeout); - timeout = setTimeout(() => { + timeout = setTimeout(async () => { + if (!companyStore.activeCompany) return; + loading = true; + error = null; + try { + const filters: Record = {}; + if (searchCode) filters.code = searchCode; + if (searchDesc) filters.description = searchDesc; + + const response = await getIdentifiers(1, pageSize, companyStore.activeCompany.id, filters); + if (response.data) { + allItems = response.data.items; + currentPage = 1; + totalItems = response.data.total; + } + } catch (err) { + error = 'Error aplicando filtros'; + console.error('Error applying filters:', err); + } finally { + loading = false; + } + const url = new URL($page.url); if (searchCode) url.searchParams.set('code', searchCode); else url.searchParams.delete('code'); @@ -41,49 +82,125 @@ if (searchDesc) url.searchParams.set('description', searchDesc); else url.searchParams.delete('description'); - url.searchParams.set('page', '1'); - goto(url, { keepFocus: true, noScroll: true }); + history.replaceState(history.state, '', url); }, 500); } + async function loadMore() { + if (loading || !hasMore || !companyStore.activeCompany) return; + loading = true; + error = null; + try { + const filters: Record = {}; + if (searchCode) filters.code = searchCode; + if (searchDesc) filters.description = searchDesc; + + const response = await getIdentifiers( + currentPage + 1, + pageSize, + companyStore.activeCompany.id, + filters + ); + if (response.data?.items) { + allItems = [...allItems, ...response.data.items]; + currentPage += 1; + totalItems = response.data.total; + } + } catch (err) { + error = 'Error cargando mas datos'; + console.error('Error loading more identifiers:', err); + } finally { + loading = false; + } + } + + async function reloadData() { + if (!companyStore.activeCompany) return; + loading = true; + error = null; + try { + const filters: Record = {}; + if (searchCode) filters.code = searchCode; + if (searchDesc) filters.description = searchDesc; + + const response = await getIdentifiers(1, pageSize, companyStore.activeCompany.id, filters); + if (response.data) { + allItems = response.data.items; + currentPage = 1; + totalItems = response.data.total; + } + } catch (err) { + error = 'Error al recargar datos'; + console.error('Error reloading identifiers:', err); + } finally { + loading = false; + } + } + function handleSuccess() { - const url = new URL($page.url); - goto(url, { invalidateAll: true }); + reloadData(); } -
+

Identificadores

Catálogo de identificadores

- -
- -
-
- -
-
- +
+ +
-
- + {#if error} +
+ {error} +
+ {/if} + + + +
+ Listado de Identificadores +
+ + +
+
+
+ +
+ +
+
+
+ +
+ Mostrando {allItems.length} de {totalItems} registros
diff --git a/frontend/src/routes/dashboard/general_catalogs/inpc/+page.svelte b/frontend/src/routes/dashboard/general_catalogs/inpc/+page.svelte index bc626c29..92990890 100644 --- a/frontend/src/routes/dashboard/general_catalogs/inpc/+page.svelte +++ b/frontend/src/routes/dashboard/general_catalogs/inpc/+page.svelte @@ -4,17 +4,21 @@ import { browser } from '$app/environment'; import { createColumns } from '$lib/components/dashboard/general_catalogs/inpc/columns'; import CreateEditDialog from '$lib/components/dashboard/general_catalogs/inpc/create-edit-dialog.svelte'; - import DataTable from '$lib/components/dashboard/general_catalogs/inpc/data-table.svelte'; + import InfiniteDataTable from '$lib/components/dashboard/common/infinite-data-table.svelte'; + import * as Card from '$lib/components/ui/card'; import { Button } from '$lib/components/ui/button'; import { Input } from '$lib/components/ui/input'; - import { Plus } from 'lucide-svelte'; + import { Plus, RefreshCw } from 'lucide-svelte'; import type { PageData } from './$types'; import { useShortcuts } from '$lib/hooks/use-shortcuts'; import { obtenerAtajosListaInpc } from '$lib/config/shortcuts/dashboard/general_catalogs/inpc/list'; + import { getINPCs } from '$lib/api/dashboard/a76/general_catalogs/inpc'; + import { companyStore } from '$lib/stores/company.svelte'; let { data }: { data: PageData } = $props(); let createDialogOpen = $state(false); + let error = $state(data.error || null); // Atajos useShortcuts( @@ -30,10 +34,48 @@ let searchMonth = $state($page.url.searchParams.get('month') || ''); let timeout: ReturnType; - function handleSearch() { + // Infinite scroll + let allItems = $state(data.inpc?.items || []); + let currentPage = $state(data.inpc?.page || 1); + let pageSize = $state(data.inpc?.page_size || 50); + let totalItems = $state(data.inpc?.total || 0); + let loading = $state(false); + let hasMore = $derived(allItems.length < totalItems); + + $effect(() => { + if (data.inpc) { + allItems = data.inpc.items || []; + currentPage = data.inpc.page || 1; + totalItems = data.inpc.total || 0; + pageSize = data.inpc.page_size || pageSize; + } + }); + + async function handleSearch() { if (!browser) return; clearTimeout(timeout); - timeout = setTimeout(() => { + timeout = setTimeout(async () => { + if (!companyStore.activeCompany) return; + loading = true; + error = null; + try { + const filters: Record = {}; + if (searchYear) filters.year = searchYear; + if (searchMonth) filters.month = searchMonth; + + const response = await getINPCs(1, pageSize, companyStore.activeCompany.id, filters); + if (response.data) { + allItems = response.data.items; + currentPage = 1; + totalItems = response.data.total; + } + } catch (err) { + error = 'Error aplicando filtros'; + console.error('Error applying filters:', err); + } finally { + loading = false; + } + const url = new URL($page.url); if (searchYear) url.searchParams.set('year', searchYear); else url.searchParams.delete('year'); @@ -41,45 +83,125 @@ if (searchMonth) url.searchParams.set('month', searchMonth); else url.searchParams.delete('month'); - url.searchParams.set('page', '1'); - goto(url, { keepFocus: true, noScroll: true }); + history.replaceState(history.state, '', url); }, 500); } + async function loadMore() { + if (loading || !hasMore || !companyStore.activeCompany) return; + loading = true; + error = null; + try { + const filters: Record = {}; + if (searchYear) filters.year = searchYear; + if (searchMonth) filters.month = searchMonth; + + const response = await getINPCs( + currentPage + 1, + pageSize, + companyStore.activeCompany.id, + filters + ); + if (response.data?.items) { + allItems = [...allItems, ...response.data.items]; + currentPage += 1; + totalItems = response.data.total; + } + } catch (err) { + error = 'Error cargando mas datos'; + console.error('Error loading more INPC:', err); + } finally { + loading = false; + } + } + + async function reloadData() { + if (!companyStore.activeCompany) return; + loading = true; + error = null; + try { + const filters: Record = {}; + if (searchYear) filters.year = searchYear; + if (searchMonth) filters.month = searchMonth; + + const response = await getINPCs(1, pageSize, companyStore.activeCompany.id, filters); + if (response.data) { + allItems = response.data.items; + currentPage = 1; + totalItems = response.data.total; + } + } catch (err) { + error = 'Error al recargar datos'; + console.error('Error reloading INPC:', err); + } finally { + loading = false; + } + } + function handleSuccess() { - const url = new URL($page.url); - goto(url, { invalidateAll: true }); + reloadData(); } -
-
+
+

INPC

Índice Nacional de Precios al Consumidor

- -
- -
-
- -
-
- +
+ +
-
- + {#if error} +
+ {error} +
+ {/if} + + + +
+ Listado de INPC +
+ + +
+
+
+ +
+ +
+
+
+ +
+ Mostrando {allItems.length} de {totalItems} registros
diff --git a/frontend/src/routes/dashboard/general_catalogs/legends/+page.svelte b/frontend/src/routes/dashboard/general_catalogs/legends/+page.svelte index 2c9ecc30..9632ba7c 100644 --- a/frontend/src/routes/dashboard/general_catalogs/legends/+page.svelte +++ b/frontend/src/routes/dashboard/general_catalogs/legends/+page.svelte @@ -1,18 +1,22 @@ -
-
+
+

Leyendas Fijas

Gestión del catálogo de leyendas fijas

- -
- -
-
- -
-
- +
+ +
-
- + {#if error} +
+ {error} +
+ {/if} + + + +
+ Listado de Leyendas +
+ + +
+
+
+ +
+ +
+
+
+ +
+ Mostrando {allItems.length} de {totalItems} registros
diff --git a/frontend/src/routes/dashboard/general_catalogs/multi_currency_types/+page.svelte b/frontend/src/routes/dashboard/general_catalogs/multi_currency_types/+page.svelte index 1dbfa9d1..004b399a 100644 --- a/frontend/src/routes/dashboard/general_catalogs/multi_currency_types/+page.svelte +++ b/frontend/src/routes/dashboard/general_catalogs/multi_currency_types/+page.svelte @@ -1,17 +1,25 @@ -
+

Tipos de Moneda Múltiple

Gestión del catálogo de tipos de moneda múltiple

- +
-
-
- + {#if error} +
+ {error}
-
- -
-
+ {/if} -
- -
+ +
Listado de Monedas
+
+
+ +
Mostrando {allItems.length} de {totalItems} registros
diff --git a/frontend/src/routes/dashboard/general_catalogs/packages/+page.svelte b/frontend/src/routes/dashboard/general_catalogs/packages/+page.svelte index 12777b93..659451d8 100644 --- a/frontend/src/routes/dashboard/general_catalogs/packages/+page.svelte +++ b/frontend/src/routes/dashboard/general_catalogs/packages/+page.svelte @@ -1,21 +1,25 @@ -
+

Bultos y Embalajes

Gestión del catálogo de bultos y embalajes

- -
- -
-
- -
-
- +
+ +
-
- + {#if error} +
+ {error} +
+ {/if} + + + +
+ Listado de Bultos +
+ + +
+
+
+ +
+ +
+
+
+ +
+ Mostrando {allItems.length} de {totalItems} registros
diff --git a/frontend/src/routes/dashboard/general_catalogs/ports/+page.svelte b/frontend/src/routes/dashboard/general_catalogs/ports/+page.svelte index 88c42d3c..2ad73e0c 100644 --- a/frontend/src/routes/dashboard/general_catalogs/ports/+page.svelte +++ b/frontend/src/routes/dashboard/general_catalogs/ports/+page.svelte @@ -4,17 +4,21 @@ import { browser } from '$app/environment'; import { createColumns } from '$lib/components/dashboard/ports/columns'; import CreateEditDialog from '$lib/components/dashboard/ports/create-edit-dialog.svelte'; - import DataTable from '$lib/components/dashboard/general_catalogs/units_of_measure/ace/data-table.svelte'; + import InfiniteDataTable from '$lib/components/dashboard/common/infinite-data-table.svelte'; + import * as Card from '$lib/components/ui/card'; import { Button } from '$lib/components/ui/button'; import { Input } from '$lib/components/ui/input'; - import { Plus } from 'lucide-svelte'; + import { Plus, RefreshCw } from 'lucide-svelte'; import type { PageData } from './$types'; import { useShortcuts } from '$lib/hooks/use-shortcuts'; import { obtenerAtajosListaPuertos } from '$lib/config/shortcuts/dashboard/general_catalogs/ports/list'; + import { portsApi } from '$lib/api/dashboard/a76/general_catalogs/ports'; + import { companyStore } from '$lib/stores/company.svelte'; let { data }: { data: PageData } = $props(); let createDialogOpen = $state(false); + let error = $state(data.items?.error || null); // Atajos useShortcuts( @@ -30,10 +34,50 @@ let searchDesc = $state($page.url.searchParams.get('description') || ''); let timeout: ReturnType; - function handleSearch() { + let allItems = $state(data.items?.items || data.items || []); + let currentPage = $state(data.items?.page || 1); + let pageSize = $state(data.items?.pageSize || data.items?.page_size || 50); + let totalItems = $state(data.items?.total || 0); + let loading = $state(false); + let hasMore = $derived(allItems.length < totalItems); + + $effect(() => { + if (data.items?.items) { + allItems = data.items.items || []; + currentPage = data.items.page || 1; + totalItems = data.items.total || 0; + pageSize = data.items.pageSize || data.items.page_size || pageSize; + } + }); + + async function handleSearch() { if (!browser) return; clearTimeout(timeout); - timeout = setTimeout(() => { + timeout = setTimeout(async () => { + if (!companyStore.activeCompany) return; + loading = true; + error = null; + try { + const params: Record = { + page: '1', + page_size: pageSize.toString() + }; + if (searchCode) params.port_code = searchCode; + if (searchDesc) params.description = searchDesc; + + const response = await portsApi.list(companyStore.activeCompany.id, params); + if (response.data?.items) { + allItems = response.data.items; + currentPage = response.data.page || 1; + totalItems = response.data.total || 0; + } + } catch (err) { + error = 'Error aplicando filtros'; + console.error('Error applying filters:', err); + } finally { + loading = false; + } + const url = new URL($page.url); if (searchCode) url.searchParams.set('port_code', searchCode); else url.searchParams.delete('port_code'); @@ -41,58 +85,117 @@ if (searchDesc) url.searchParams.set('description', searchDesc); else url.searchParams.delete('description'); - url.searchParams.set('page', '1'); - goto(url, { keepFocus: true, noScroll: true }); + history.replaceState(history.state, '', url); }, 500); } + async function loadMore() { + if (loading || !hasMore || !companyStore.activeCompany) return; + loading = true; + error = null; + try { + const params: Record = { + page: (currentPage + 1).toString(), + page_size: pageSize.toString() + }; + if (searchCode) params.port_code = searchCode; + if (searchDesc) params.description = searchDesc; + + const response = await portsApi.list(companyStore.activeCompany.id, params); + if (response.data?.items) { + allItems = [...allItems, ...response.data.items]; + currentPage += 1; + totalItems = response.data.total || 0; + } + } catch (err) { + error = 'Error cargando mas datos'; + console.error('Error loading more ports:', err); + } finally { + loading = false; + } + } + + async function reloadData() { + if (!companyStore.activeCompany) return; + loading = true; + error = null; + try { + const params: Record = { + page: '1', + page_size: pageSize.toString() + }; + if (searchCode) params.port_code = searchCode; + if (searchDesc) params.description = searchDesc; + + const response = await portsApi.list(companyStore.activeCompany.id, params); + if (response.data?.items) { + allItems = response.data.items; + currentPage = response.data.page || 1; + totalItems = response.data.total || 0; + } + } catch (err) { + error = 'Error al recargar datos'; + console.error('Error reloading ports:', err); + } finally { + loading = false; + } + } + function handleSuccess() { - const url = new URL($page.url); - goto(url, { invalidateAll: true }); + reloadData(); } -
+

Puertos

Catálogo de puertos

- +
+ + +
- {#if data.items?.error} + {#if error}
- {data.items.error} + {error}
{/if} -
-
- -
-
- -
-
+ + +
+ Listado de Puertos +
+ + +
+
+
+ +
+ +
+
+
-
- -
+
Mostrando {allItems.length} de {totalItems} registros
diff --git a/frontend/src/routes/dashboard/general_catalogs/prevalidators/+page.svelte b/frontend/src/routes/dashboard/general_catalogs/prevalidators/+page.svelte index 81899bfd..fd4ed81e 100644 --- a/frontend/src/routes/dashboard/general_catalogs/prevalidators/+page.svelte +++ b/frontend/src/routes/dashboard/general_catalogs/prevalidators/+page.svelte @@ -2,17 +2,21 @@ import { goto } from '$app/navigation'; import { page } from '$app/stores'; import { browser } from '$app/environment'; + import * as Card from '$lib/components/ui/card'; import { Button } from '$lib/components/ui/button'; import { Input } from '$lib/components/ui/input'; - import { Plus } from 'lucide-svelte'; - import DataTable from '$lib/components/dashboard/general_catalogs/prevalidators/data-table.svelte'; + import { Plus, RefreshCw } from 'lucide-svelte'; + import InfiniteDataTable from '$lib/components/dashboard/common/infinite-data-table.svelte'; import { createColumns } from '$lib/components/dashboard/general_catalogs/prevalidators/columns'; import CreateEditDialog from '$lib/components/dashboard/general_catalogs/prevalidators/create-edit-dialog.svelte'; import { useShortcuts } from '$lib/hooks/use-shortcuts'; import { obtenerAtajosListaPrevalidadores } from '$lib/config/shortcuts/dashboard/general_catalogs/prevalidators/list'; + import { getPrevalidators } from '$lib/api/dashboard/a76/general_catalogs/prevalidators'; + import { companyStore } from '$lib/stores/company.svelte'; let { data } = $props(); let dialogOpen = $state(false); + let error = $state(data.error || null); // Atajos useShortcuts( @@ -27,15 +31,47 @@ let searchDesc = $state($page.url.searchParams.get('description') || ''); let timeout: ReturnType; - function handleSuccess() { - const url = new URL($page.url); - goto(url, { invalidateAll: true }); - } + let allItems = $state(data.prevalidators?.items || []); + let currentPage = $state(data.prevalidators?.page || 1); + let pageSize = $state(data.prevalidators?.page_size || 50); + let totalItems = $state(data.prevalidators?.total || 0); + let loading = $state(false); + let hasMore = $derived(allItems.length < totalItems); - function handleSearch() { + $effect(() => { + if (data.prevalidators) { + allItems = data.prevalidators.items || []; + currentPage = data.prevalidators.page || 1; + totalItems = data.prevalidators.total || 0; + pageSize = data.prevalidators.page_size || pageSize; + } + }); + + async function handleSearch() { if (!browser) return; clearTimeout(timeout); - timeout = setTimeout(() => { + timeout = setTimeout(async () => { + if (!companyStore.activeCompany) return; + loading = true; + error = null; + try { + const filters: Record = {}; + if (searchCode) filters.code = searchCode; + if (searchDesc) filters.description = searchDesc; + + const response = await getPrevalidators(1, pageSize, filters, companyStore.activeCompany.id); + if (response?.items) { + allItems = response.items; + currentPage = 1; + totalItems = response.total; + } + } catch (err) { + error = 'Error aplicando filtros'; + console.error('Error applying filters:', err); + } finally { + loading = false; + } + const url = new URL($page.url); if (searchCode) url.searchParams.set('code', searchCode); else url.searchParams.delete('code'); @@ -43,45 +79,98 @@ if (searchDesc) url.searchParams.set('description', searchDesc); else url.searchParams.delete('description'); - url.searchParams.set('page', '1'); - goto(url, { keepFocus: true, noScroll: true }); + history.replaceState(history.state, '', url); }, 500); } + + async function loadMore() { + if (loading || !hasMore || !companyStore.activeCompany) return; + loading = true; + error = null; + try { + const filters: Record = {}; + if (searchCode) filters.code = searchCode; + if (searchDesc) filters.description = searchDesc; + + const response = await getPrevalidators( + currentPage + 1, + pageSize, + filters, + companyStore.activeCompany.id + ); + if (response?.items) { + allItems = [...allItems, ...response.items]; + currentPage += 1; + totalItems = response.total; + } + } catch (err) { + error = 'Error cargando mas datos'; + console.error('Error loading more prevalidators:', err); + } finally { + loading = false; + } + } + + async function reloadData() { + if (!companyStore.activeCompany) return; + loading = true; + error = null; + try { + const filters: Record = {}; + if (searchCode) filters.code = searchCode; + if (searchDesc) filters.description = searchDesc; + + const response = await getPrevalidators(1, pageSize, filters, companyStore.activeCompany.id); + if (response?.items) { + allItems = response.items; + currentPage = 1; + totalItems = response.total; + } + } catch (err) { + error = 'Error al recargar datos'; + console.error('Error reloading prevalidators:', err); + } finally { + loading = false; + } + } + + function handleSuccess() { + reloadData(); + } -
+

Prevalidadores

Catálogo de prevalidadores

- -
- -
-
- -
-
- +
+ +
-
- -
+ {#if error} +
+ {error} +
+ {/if} + + + +
+ Listado de Prevalidadores +
+ + +
+
+
+
+
+ +
Mostrando {allItems.length} de {totalItems} registros
diff --git a/frontend/src/routes/dashboard/general_catalogs/seal/+page.svelte b/frontend/src/routes/dashboard/general_catalogs/seal/+page.svelte index 562bb586..fac039f8 100644 --- a/frontend/src/routes/dashboard/general_catalogs/seal/+page.svelte +++ b/frontend/src/routes/dashboard/general_catalogs/seal/+page.svelte @@ -1,8 +1,9 @@ -
-
+
+

Sellos

Gestiona los sellos de tu empresa

- +
+ + +
{#if error} -
+

{error}

{/if} -
-
- -
-
+ + +
+ Listado de Sellos +
+ +
+
+
+ +
+ +
+
+
-
- +
+ Mostrando {allItems.length} de {totalItems || allItems.length} registros
diff --git a/frontend/src/routes/dashboard/general_catalogs/signatures/+page.svelte b/frontend/src/routes/dashboard/general_catalogs/signatures/+page.svelte index 34af6e59..a0e46d78 100644 --- a/frontend/src/routes/dashboard/general_catalogs/signatures/+page.svelte +++ b/frontend/src/routes/dashboard/general_catalogs/signatures/+page.svelte @@ -4,15 +4,19 @@ import { browser } from '$app/environment'; import { Button } from '$lib/components/ui/button'; import { Input } from '$lib/components/ui/input'; - import { Plus } from 'lucide-svelte'; - import DataTable from '$lib/components/dashboard/general_catalogs/signatures/data-table.svelte'; + import * as Card from '$lib/components/ui/card'; + import { Plus, RefreshCw } from 'lucide-svelte'; + import InfiniteDataTable from '$lib/components/dashboard/common/infinite-data-table.svelte'; import { createColumns } from '$lib/components/dashboard/general_catalogs/signatures/columns'; import CreateEditDialog from '$lib/components/dashboard/general_catalogs/signatures/create-edit-dialog.svelte'; import { useShortcuts } from '$lib/hooks/use-shortcuts'; import { obtenerAtajosListaFirmas } from '$lib/config/shortcuts/dashboard/general_catalogs/signatures/list'; + import { getSignatures } from '$lib/api/dashboard/a76/general_catalogs/signatures'; + import { companyStore } from '$lib/stores/company.svelte'; let { data } = $props(); let dialogOpen = $state(false); + let error = $state(data.error || null); // Atajos useShortcuts( @@ -26,50 +30,138 @@ let searchCode = $state($page.url.searchParams.get('code') || ''); let timeout: ReturnType; - function handleSuccess() { - const url = new URL($page.url); - goto(url, { invalidateAll: true }); - } + let allItems = $state(data.signatures?.items || []); + let currentPage = $state(data.signatures?.page || 1); + let pageSize = $state(data.signatures?.page_size || 50); + let totalItems = $state(data.signatures?.total || 0); + let loading = $state(false); + let hasMore = $derived(allItems.length < totalItems); - function handleSearch() { + $effect(() => { + if (data.signatures) { + allItems = data.signatures.items || []; + currentPage = data.signatures.page || 1; + totalItems = data.signatures.total || 0; + pageSize = data.signatures.page_size || pageSize; + } + }); + + async function handleSearch() { if (!browser) return; clearTimeout(timeout); - timeout = setTimeout(() => { + timeout = setTimeout(async () => { + if (!companyStore.activeCompany) return; + loading = true; + error = null; + try { + const filters: Record = {}; + if (searchCode) filters.code = searchCode; + + const response = await getSignatures( + 1, + pageSize, + companyStore.activeCompany.id, + filters + ); + if (response?.items) { + allItems = response.items; + currentPage = 1; + totalItems = response.total; + } + } catch (err) { + error = 'Error aplicando filtros'; + console.error('Error applying filters:', err); + } finally { + loading = false; + } + const url = new URL($page.url); if (searchCode) url.searchParams.set('code', searchCode); else url.searchParams.delete('code'); - url.searchParams.set('page', '1'); - goto(url, { keepFocus: true, noScroll: true }); + history.replaceState(history.state, '', url); }, 500); } + + async function loadMore() { + if (loading || !hasMore || !companyStore.activeCompany) return; + loading = true; + error = null; + try { + const filters: Record = {}; + if (searchCode) filters.code = searchCode; + + const response = await getSignatures( + currentPage + 1, + pageSize, + companyStore.activeCompany.id, + filters + ); + if (response?.items) { + allItems = [...allItems, ...response.items]; + currentPage += 1; + totalItems = response.total; + } + } catch (err) { + error = 'Error cargando mas datos'; + console.error('Error loading more signatures:', err); + } finally { + loading = false; + } + } + + async function reloadData() { + if (!companyStore.activeCompany) return; + loading = true; + error = null; + try { + const filters: Record = {}; + if (searchCode) filters.code = searchCode; + + const response = await getSignatures( + 1, + pageSize, + companyStore.activeCompany.id, + filters + ); + if (response?.items) { + allItems = response.items; + currentPage = 1; + totalItems = response.total; + } + } catch (err) { + error = 'Error al recargar datos'; + console.error('Error reloading signatures:', err); + } finally { + loading = false; + } + } + + function handleSuccess() { + reloadData(); + } -
+

Firmas Electrónicas

Gestión del catálogo de firmas electrónicas

- +
-
-
- + {#if error} +
+ {error}
-
+ {/if} -
- -
+ +
Listado de Firmas
+
+
+ +
Mostrando {allItems.length} de {totalItems} registros
diff --git a/frontend/src/routes/dashboard/general_catalogs/tariff-fractions/+page.svelte b/frontend/src/routes/dashboard/general_catalogs/tariff-fractions/+page.svelte index 9ad3119a..8fc9313b 100644 --- a/frontend/src/routes/dashboard/general_catalogs/tariff-fractions/+page.svelte +++ b/frontend/src/routes/dashboard/general_catalogs/tariff-fractions/+page.svelte @@ -89,145 +89,100 @@ } -
- - - - Catálogo de Fracciones SITAR - SCAII - -

Nomenclatura arancelaria mexicana completa

+
+
+
+

Catálogo de Fracciones SITAR - SCAII

+

Nomenclatura arancelaria mexicana completa

+
+ +
+ + + +
+ Listado de Fracciones +
+ + +
+
- - -
- -
-
- - -
- -
- - -
-
- {#if isLoading} -
- - Cargando... -
- {:else} - Mostrando {tariffFractions.length} de {totalRecords} fracciones arancelarias - {#if searchQuery} - (filtrado) - {/if} - {/if} -
- {#if totalPages > 1} -
- Página {currentPage} de {totalPages} -
- {/if} -
- - -
- - + +
+ + + + Código + Fracción + Descripción + NICO + UMT + Adv. Impo + Adv. Expo + + + + {#if tariffFractions.length === 0} - Código - Fracción - Descripción - NICO - UMT - Adv. Impo - Adv. Expo + + {#if isLoading} + Cargando fracciones arancelarias... + {:else if searchQuery} + No se encontraron fracciones que coincidan con la búsqueda + {:else} + No hay fracciones arancelarias disponibles + {/if} + - - - {#if tariffFractions.length === 0} - - - {#if isLoading} - Cargando fracciones arancelarias... - {:else if searchQuery} - No se encontraron fracciones que coincidan con la búsqueda - {:else} - No hay fracciones arancelarias disponibles - {/if} - + {:else} + {#each tariffFractions as fraction (fraction.id)} + + {fraction.code} + {fraction.fraction} + {fraction.description || '-'} + {fraction.nico || '-'} + {fraction.umt || '-'} + {fraction.adv_impo || '-'} + {fraction.adv_expo || '-'} - {:else} - {#each tariffFractions as fraction (fraction.id)} - - {fraction.code} - {fraction.fraction} - - {fraction.description || '-'} - - {fraction.nico || '-'} - {fraction.umt || '-'} - {fraction.adv_impo || '-'} - {fraction.adv_expo || '-'} - - {/each} - {/if} - - -
- - - {#if totalPages > 1} -
- - - - Página {currentPage} de {totalPages} - - - -
- {/if} + {/each} + {/if} + +
+ +
+ Mostrando {tariffFractions.length} de {totalRecords} fracciones arancelarias + {#if searchQuery} + + Filtrado + {/if} +
+ + {#if totalPages > 1} +
+ + + + +
+ {/if}
diff --git a/frontend/src/routes/dashboard/general_catalogs/tariff-fractions/canadian/+page.svelte b/frontend/src/routes/dashboard/general_catalogs/tariff-fractions/canadian/+page.svelte index 5a67d55e..63fab84b 100644 --- a/frontend/src/routes/dashboard/general_catalogs/tariff-fractions/canadian/+page.svelte +++ b/frontend/src/routes/dashboard/general_catalogs/tariff-fractions/canadian/+page.svelte @@ -3,9 +3,15 @@ import * as m from '$lib/paraglide/messages.js'; -
-
-

{m['sidebar.fractions.canadian']()}

+
+
+
+

{m['sidebar.fractions.canadian']()}

+

Catálogo de fracciones arancelarias canadienses

+
+
+ +
+
-
diff --git a/frontend/src/routes/dashboard/general_catalogs/trailers/+page.svelte b/frontend/src/routes/dashboard/general_catalogs/trailers/+page.svelte index 596c3d13..0331dc38 100644 --- a/frontend/src/routes/dashboard/general_catalogs/trailers/+page.svelte +++ b/frontend/src/routes/dashboard/general_catalogs/trailers/+page.svelte @@ -1,12 +1,13 @@ -
+
-

Trailers

+

Trailers

Gestión del catálogo de trailers de la compañía

- +
-
- - -
+ +
Listado de Trailers
+ {#if loading && data.length === 0}
Cargando trailers...
{:else}
{/if}
+
- {#if loading && data.length === 0} -
- Cargando trailers... -
- {:else} - - {/if} +
Mostrando {data.length} de {totalItems} registros
diff --git a/frontend/src/routes/dashboard/general_catalogs/transporters/+page.svelte b/frontend/src/routes/dashboard/general_catalogs/transporters/+page.svelte index 150e006b..f14bf171 100644 --- a/frontend/src/routes/dashboard/general_catalogs/transporters/+page.svelte +++ b/frontend/src/routes/dashboard/general_catalogs/transporters/+page.svelte @@ -1,12 +1,13 @@ -
+
-

Transportistas

+

Transportistas

Gestión del catálogo de líneas transportistas

- +
-
- - -
+ +
Listado de Transportistas
+ {#if loading && data.length === 0}
Cargando transportistas...
{:else}
{/if}
+
- {#if loading && data.length === 0} -
- Cargando transportistas... -
- {:else} - - {/if} +
Mostrando {data.length} de {totalItems} registros
diff --git a/frontend/src/routes/dashboard/general_catalogs/unit_conversions/+page.svelte b/frontend/src/routes/dashboard/general_catalogs/unit_conversions/+page.svelte index bc274ff2..ea00c786 100644 --- a/frontend/src/routes/dashboard/general_catalogs/unit_conversions/+page.svelte +++ b/frontend/src/routes/dashboard/general_catalogs/unit_conversions/+page.svelte @@ -4,17 +4,21 @@ import { browser } from '$app/environment'; import { createColumns } from '$lib/components/dashboard/general_catalogs/unit_conversions/columns'; import CreateEditDialog from '$lib/components/dashboard/general_catalogs/unit_conversions/create-edit-dialog.svelte'; - import DataTable from '$lib/components/dashboard/general_catalogs/unit_conversions/data-table.svelte'; + import InfiniteDataTable from '$lib/components/dashboard/common/infinite-data-table.svelte'; + import * as Card from '$lib/components/ui/card'; import { Button } from '$lib/components/ui/button'; import { Input } from '$lib/components/ui/input'; - import { Plus } from 'lucide-svelte'; + import { Plus, RefreshCw } from 'lucide-svelte'; import type { PageData } from './$types'; import { useShortcuts } from '$lib/hooks/use-shortcuts'; import { obtenerAtajosListaConversiones } from '$lib/config/shortcuts/dashboard/general_catalogs/unit_conversions/list'; + import { getUnitConversions } from '$lib/api/dashboard/a76/general_catalogs/unit-conversions'; + import { companyStore } from '$lib/stores/company.svelte'; let { data }: { data: PageData } = $props(); let createDialogOpen = $state(false); + let error = $state(data.error || null); // Atajos useShortcuts( @@ -30,10 +34,52 @@ let searchTo = $state($page.url.searchParams.get('to_unit_code') || ''); let timeout: ReturnType; - function handleSearch() { + let allItems = $state(data.conversions?.items || []); + let currentPage = $state(data.conversions?.page || 1); + let pageSize = $state(data.conversions?.page_size || 50); + let totalItems = $state(data.conversions?.total || 0); + let loading = $state(false); + let hasMore = $derived(allItems.length < totalItems); + + $effect(() => { + if (data.conversions) { + allItems = data.conversions.items || []; + currentPage = data.conversions.page || 1; + totalItems = data.conversions.total || 0; + pageSize = data.conversions.page_size || pageSize; + } + }); + + async function handleSearch() { if (!browser) return; clearTimeout(timeout); - timeout = setTimeout(() => { + timeout = setTimeout(async () => { + if (!companyStore.activeCompany) return; + loading = true; + error = null; + try { + const filters: Record = {}; + if (searchFrom) filters.from_unit_code = searchFrom; + if (searchTo) filters.to_unit_code = searchTo; + + const response = await getUnitConversions( + 1, + pageSize, + companyStore.activeCompany.id, + filters + ); + if (response?.items) { + allItems = response.items; + currentPage = 1; + totalItems = response.total; + } + } catch (err) { + error = 'Error aplicando filtros'; + console.error('Error applying filters:', err); + } finally { + loading = false; + } + const url = new URL($page.url); if (searchFrom) url.searchParams.set('from_unit_code', searchFrom); else url.searchParams.delete('from_unit_code'); @@ -41,46 +87,92 @@ if (searchTo) url.searchParams.set('to_unit_code', searchTo); else url.searchParams.delete('to_unit_code'); - url.searchParams.set('page', '1'); - goto(url, { keepFocus: true, noScroll: true }); + history.replaceState(history.state, '', url); }, 500); } + async function loadMore() { + if (loading || !hasMore || !companyStore.activeCompany) return; + loading = true; + error = null; + try { + const filters: Record = {}; + if (searchFrom) filters.from_unit_code = searchFrom; + if (searchTo) filters.to_unit_code = searchTo; + + const response = await getUnitConversions( + currentPage + 1, + pageSize, + companyStore.activeCompany.id, + filters + ); + if (response?.items) { + allItems = [...allItems, ...response.items]; + currentPage += 1; + totalItems = response.total; + } + } catch (err) { + error = 'Error cargando mas datos'; + console.error('Error loading more unit conversions:', err); + } finally { + loading = false; + } + } + + async function reloadData() { + if (!companyStore.activeCompany) return; + loading = true; + error = null; + try { + const filters: Record = {}; + if (searchFrom) filters.from_unit_code = searchFrom; + if (searchTo) filters.to_unit_code = searchTo; + + const response = await getUnitConversions( + 1, + pageSize, + companyStore.activeCompany.id, + filters + ); + if (response?.items) { + allItems = response.items; + currentPage = 1; + totalItems = response.total; + } + } catch (err) { + error = 'Error al recargar datos'; + console.error('Error reloading unit conversions:', err); + } finally { + loading = false; + } + } + function handleSuccess() { - const url = new URL($page.url); - goto(url, { invalidateAll: true }); + reloadData(); } -
+

Conversiones de Unidades

Catálogo de conversiones de unidades de medida

- +
-
-
- + {#if error} +
+ {error}
-
- -
-
+ {/if} -
- -
+ +
Listado de Conversiones
+
+
+ +
Mostrando {allItems.length} de {totalItems} registros
diff --git a/frontend/src/routes/dashboard/general_catalogs/units_of_measure/ace/+page.svelte b/frontend/src/routes/dashboard/general_catalogs/units_of_measure/ace/+page.svelte index 664840ef..a4bc68fb 100644 --- a/frontend/src/routes/dashboard/general_catalogs/units_of_measure/ace/+page.svelte +++ b/frontend/src/routes/dashboard/general_catalogs/units_of_measure/ace/+page.svelte @@ -4,17 +4,21 @@ import { browser } from '$app/environment'; import { createColumns } from '$lib/components/dashboard/general_catalogs/units_of_measure/ace/columns'; import CreateEditDialog from '$lib/components/dashboard/general_catalogs/units_of_measure/ace/create-edit-dialog.svelte'; - import DataTable from '$lib/components/dashboard/general_catalogs/units_of_measure/ace/data-table.svelte'; + import InfiniteDataTable from '$lib/components/dashboard/common/infinite-data-table.svelte'; + import * as Card from '$lib/components/ui/card'; import { Button } from '$lib/components/ui/button'; import { Input } from '$lib/components/ui/input'; - import { Plus } from 'lucide-svelte'; + import { Plus, RefreshCw } from 'lucide-svelte'; import type { PageData } from './$types'; import { useShortcuts } from '$lib/hooks/use-shortcuts'; import { obtenerAtajosListaUnidadesACE } from '$lib/config/shortcuts/dashboard/general_catalogs/units_of_measure/ace/list'; + import { getUnitsOfMeasureACE } from '$lib/api/dashboard/a76/general_catalogs/units-of-measure'; + import { companyStore } from '$lib/stores/company.svelte'; let { data }: { data: PageData } = $props(); let createDialogOpen = $state(false); + let error = $state(data.error || null); // Atajos useShortcuts( @@ -30,10 +34,52 @@ let searchDesc = $state($page.url.searchParams.get('description') || ''); let timeout: ReturnType; - function handleSearch() { + let allItems = $state(data.ace_units?.items || []); + let currentPage = $state(data.ace_units?.page || 1); + let pageSize = $state(data.ace_units?.page_size || 50); + let totalItems = $state(data.ace_units?.total || 0); + let loading = $state(false); + let hasMore = $derived(allItems.length < totalItems); + + $effect(() => { + if (data.ace_units) { + allItems = data.ace_units.items || []; + currentPage = data.ace_units.page || 1; + totalItems = data.ace_units.total || 0; + pageSize = data.ace_units.page_size || pageSize; + } + }); + + async function handleSearch() { if (!browser) return; clearTimeout(timeout); - timeout = setTimeout(() => { + timeout = setTimeout(async () => { + if (!companyStore.activeCompany) return; + loading = true; + error = null; + try { + const filters: Record = {}; + if (searchCode) filters.code = searchCode; + if (searchDesc) filters.description = searchDesc; + + const response = await getUnitsOfMeasureACE( + 1, + pageSize, + companyStore.activeCompany.id, + filters + ); + if (response.data) { + allItems = response.data.items; + currentPage = 1; + totalItems = response.data.total; + } + } catch (err) { + error = 'Error aplicando filtros'; + console.error('Error applying filters:', err); + } finally { + loading = false; + } + const url = new URL($page.url); if (searchCode) url.searchParams.set('code', searchCode); else url.searchParams.delete('code'); @@ -41,50 +87,92 @@ if (searchDesc) url.searchParams.set('description', searchDesc); else url.searchParams.delete('description'); - url.searchParams.set('page', '1'); - goto(url, { keepFocus: true, noScroll: true }); + history.replaceState(history.state, '', url); }, 500); } + async function loadMore() { + if (loading || !hasMore || !companyStore.activeCompany) return; + loading = true; + error = null; + try { + const filters: Record = {}; + if (searchCode) filters.code = searchCode; + if (searchDesc) filters.description = searchDesc; + + const response = await getUnitsOfMeasureACE( + currentPage + 1, + pageSize, + companyStore.activeCompany.id, + filters + ); + if (response.data?.items) { + allItems = [...allItems, ...response.data.items]; + currentPage += 1; + totalItems = response.data.total; + } + } catch (err) { + error = 'Error cargando mas datos'; + console.error('Error loading more ACE units:', err); + } finally { + loading = false; + } + } + + async function reloadData() { + if (!companyStore.activeCompany) return; + loading = true; + error = null; + try { + const filters: Record = {}; + if (searchCode) filters.code = searchCode; + if (searchDesc) filters.description = searchDesc; + + const response = await getUnitsOfMeasureACE( + 1, + pageSize, + companyStore.activeCompany.id, + filters + ); + if (response.data) { + allItems = response.data.items; + currentPage = 1; + totalItems = response.data.total; + } + } catch (err) { + error = 'Error al recargar datos'; + console.error('Error reloading ACE units:', err); + } finally { + loading = false; + } + } + function handleSuccess() { - const url = new URL($page.url); - goto(url, { invalidateAll: true }); + reloadData(); } -
+

Unidades de Medida ACE

Catálogo de unidades de medida ACE

- +
-
-
- + {#if error} +
+ {error}
-
- -
-
+ {/if} -
- -
+ +
Listado de Unidades ACE
+
+
+ +
Mostrando {allItems.length} de {totalItems} registros
diff --git a/frontend/src/routes/dashboard/general_catalogs/units_of_measure/american/+page.svelte b/frontend/src/routes/dashboard/general_catalogs/units_of_measure/american/+page.svelte index 41f27a3f..38bfedf3 100644 --- a/frontend/src/routes/dashboard/general_catalogs/units_of_measure/american/+page.svelte +++ b/frontend/src/routes/dashboard/general_catalogs/units_of_measure/american/+page.svelte @@ -3,18 +3,22 @@ import { goto } from '$app/navigation'; import { browser } from '$app/environment'; import { createColumns } from '$lib/components/dashboard/general_catalogs/units_of_measure/american/columns'; - import DataTable from '$lib/components/dashboard/general_catalogs/units_of_measure/american/data-table.svelte'; + import InfiniteDataTable from '$lib/components/dashboard/common/infinite-data-table.svelte'; import CreateEditDialog from '$lib/components/dashboard/general_catalogs/units_of_measure/american/create-edit-dialog.svelte'; + import * as Card from '$lib/components/ui/card'; import { Button } from '$lib/components/ui/button'; import { Input } from '$lib/components/ui/input'; - import { Plus } from 'lucide-svelte'; + import { Plus, RefreshCw } from 'lucide-svelte'; import type { PageData } from './$types'; import { useShortcuts } from '$lib/hooks/use-shortcuts'; import { obtenerAtajosListaUnidadesAmericanas } from '$lib/config/shortcuts/dashboard/general_catalogs/units_of_measure/american/list'; + import { getUnitsOfMeasureAmerican } from '$lib/api/dashboard/a76/general_catalogs/units-of-measure'; + import { companyStore } from '$lib/stores/company.svelte'; let { data }: { data: PageData } = $props(); let createDialogOpen = $state(false); + let error = $state(data.error || null); // Atajos useShortcuts( @@ -30,10 +34,52 @@ let searchDesc = $state($page.url.searchParams.get('description') || ''); let timeout: ReturnType; - function handleSearch() { + let allItems = $state(data.american_units?.items || []); + let currentPage = $state(data.american_units?.page || 1); + let pageSize = $state(data.american_units?.page_size || 50); + let totalItems = $state(data.american_units?.total || 0); + let loading = $state(false); + let hasMore = $derived(allItems.length < totalItems); + + $effect(() => { + if (data.american_units) { + allItems = data.american_units.items || []; + currentPage = data.american_units.page || 1; + totalItems = data.american_units.total || 0; + pageSize = data.american_units.page_size || pageSize; + } + }); + + async function handleSearch() { if (!browser) return; clearTimeout(timeout); - timeout = setTimeout(() => { + timeout = setTimeout(async () => { + if (!companyStore.activeCompany) return; + loading = true; + error = null; + try { + const filters: Record = {}; + if (searchCode) filters.code = searchCode; + if (searchDesc) filters.description = searchDesc; + + const response = await getUnitsOfMeasureAmerican( + 1, + pageSize, + companyStore.activeCompany.id, + filters + ); + if (response.data) { + allItems = response.data.items; + currentPage = 1; + totalItems = response.data.total; + } + } catch (err) { + error = 'Error aplicando filtros'; + console.error('Error applying filters:', err); + } finally { + loading = false; + } + const url = new URL($page.url); if (searchCode) url.searchParams.set('code', searchCode); else url.searchParams.delete('code'); @@ -41,50 +87,92 @@ if (searchDesc) url.searchParams.set('description', searchDesc); else url.searchParams.delete('description'); - url.searchParams.set('page', '1'); - goto(url, { keepFocus: true, noScroll: true }); + history.replaceState(history.state, '', url); }, 500); } + async function loadMore() { + if (loading || !hasMore || !companyStore.activeCompany) return; + loading = true; + error = null; + try { + const filters: Record = {}; + if (searchCode) filters.code = searchCode; + if (searchDesc) filters.description = searchDesc; + + const response = await getUnitsOfMeasureAmerican( + currentPage + 1, + pageSize, + companyStore.activeCompany.id, + filters + ); + if (response.data?.items) { + allItems = [...allItems, ...response.data.items]; + currentPage += 1; + totalItems = response.data.total; + } + } catch (err) { + error = 'Error cargando mas datos'; + console.error('Error loading more American units:', err); + } finally { + loading = false; + } + } + + async function reloadData() { + if (!companyStore.activeCompany) return; + loading = true; + error = null; + try { + const filters: Record = {}; + if (searchCode) filters.code = searchCode; + if (searchDesc) filters.description = searchDesc; + + const response = await getUnitsOfMeasureAmerican( + 1, + pageSize, + companyStore.activeCompany.id, + filters + ); + if (response.data) { + allItems = response.data.items; + currentPage = 1; + totalItems = response.data.total; + } + } catch (err) { + error = 'Error al recargar datos'; + console.error('Error reloading American units:', err); + } finally { + loading = false; + } + } + function handleSuccess() { - const url = new URL($page.url); - goto(url, { invalidateAll: true }); + reloadData(); } -
+

Unidades de Medida Americanas

Catálogo de unidades de medida Americanas

- +
-
-
- + {#if error} +
+ {error}
-
- -
-
+ {/if} -
- -
+ +
Listado de Unidades Americanas
+
+
+ +
Mostrando {allItems.length} de {totalItems} registros
diff --git a/frontend/src/routes/dashboard/general_catalogs/units_of_measure/customs/+page.svelte b/frontend/src/routes/dashboard/general_catalogs/units_of_measure/customs/+page.svelte index 671625b1..e8e8fe79 100644 --- a/frontend/src/routes/dashboard/general_catalogs/units_of_measure/customs/+page.svelte +++ b/frontend/src/routes/dashboard/general_catalogs/units_of_measure/customs/+page.svelte @@ -3,18 +3,22 @@ import { goto } from '$app/navigation'; import { browser } from '$app/environment'; import { createColumns } from '$lib/components/dashboard/general_catalogs/units_of_measure/customs/columns'; - import DataTable from '$lib/components/dashboard/general_catalogs/units_of_measure/customs/data-table.svelte'; + import InfiniteDataTable from '$lib/components/dashboard/common/infinite-data-table.svelte'; import CreateEditDialog from '$lib/components/dashboard/general_catalogs/units_of_measure/customs/create-edit-dialog.svelte'; + import * as Card from '$lib/components/ui/card'; import { Button } from '$lib/components/ui/button'; import { Input } from '$lib/components/ui/input'; - import { Plus } from 'lucide-svelte'; + import { Plus, RefreshCw } from 'lucide-svelte'; import type { PageData } from './$types'; import { useShortcuts } from '$lib/hooks/use-shortcuts'; import { obtenerAtajosListaUnidadesAduanas } from '$lib/config/shortcuts/dashboard/general_catalogs/units_of_measure/customs/list'; + import { getUnitsOfMeasureCustoms } from '$lib/api/dashboard/a76/general_catalogs/units-of-measure'; + import { companyStore } from '$lib/stores/company.svelte'; let { data }: { data: PageData } = $props(); let createDialogOpen = $state(false); + let error = $state(data.error || null); // Atajos useShortcuts( @@ -30,10 +34,52 @@ let searchDesc = $state($page.url.searchParams.get('description') || ''); let timeout: ReturnType; - function handleSearch() { + let allItems = $state(data.customs_units?.items || []); + let currentPage = $state(data.customs_units?.page || 1); + let pageSize = $state(data.customs_units?.page_size || 50); + let totalItems = $state(data.customs_units?.total || 0); + let loading = $state(false); + let hasMore = $derived(allItems.length < totalItems); + + $effect(() => { + if (data.customs_units) { + allItems = data.customs_units.items || []; + currentPage = data.customs_units.page || 1; + totalItems = data.customs_units.total || 0; + pageSize = data.customs_units.page_size || pageSize; + } + }); + + async function handleSearch() { if (!browser) return; clearTimeout(timeout); - timeout = setTimeout(() => { + timeout = setTimeout(async () => { + if (!companyStore.activeCompany) return; + loading = true; + error = null; + try { + const filters: Record = {}; + if (searchCode) filters.code = searchCode; + if (searchDesc) filters.description = searchDesc; + + const response = await getUnitsOfMeasureCustoms( + 1, + pageSize, + companyStore.activeCompany.id, + filters + ); + if (response.data) { + allItems = response.data.items; + currentPage = 1; + totalItems = response.data.total; + } + } catch (err) { + error = 'Error aplicando filtros'; + console.error('Error applying filters:', err); + } finally { + loading = false; + } + const url = new URL($page.url); if (searchCode) url.searchParams.set('code', searchCode); else url.searchParams.delete('code'); @@ -41,50 +87,92 @@ if (searchDesc) url.searchParams.set('description', searchDesc); else url.searchParams.delete('description'); - url.searchParams.set('page', '1'); - goto(url, { keepFocus: true, noScroll: true }); + history.replaceState(history.state, '', url); }, 500); } + async function loadMore() { + if (loading || !hasMore || !companyStore.activeCompany) return; + loading = true; + error = null; + try { + const filters: Record = {}; + if (searchCode) filters.code = searchCode; + if (searchDesc) filters.description = searchDesc; + + const response = await getUnitsOfMeasureCustoms( + currentPage + 1, + pageSize, + companyStore.activeCompany.id, + filters + ); + if (response.data?.items) { + allItems = [...allItems, ...response.data.items]; + currentPage += 1; + totalItems = response.data.total; + } + } catch (err) { + error = 'Error cargando mas datos'; + console.error('Error loading more customs units:', err); + } finally { + loading = false; + } + } + + async function reloadData() { + if (!companyStore.activeCompany) return; + loading = true; + error = null; + try { + const filters: Record = {}; + if (searchCode) filters.code = searchCode; + if (searchDesc) filters.description = searchDesc; + + const response = await getUnitsOfMeasureCustoms( + 1, + pageSize, + companyStore.activeCompany.id, + filters + ); + if (response.data) { + allItems = response.data.items; + currentPage = 1; + totalItems = response.data.total; + } + } catch (err) { + error = 'Error al recargar datos'; + console.error('Error reloading customs units:', err); + } finally { + loading = false; + } + } + function handleSuccess() { - const url = new URL($page.url); - goto(url, { invalidateAll: true }); + reloadData(); } -
+

Unidades de Medida Aduanas MEX

Catálogo de unidades de medida para aduanas mexicanas

- +
-
-
- + {#if error} +
+ {error}
-
- -
-
+ {/if} -
- -
+ +
Listado de Unidades Aduanas MX
+
+
+ +
Mostrando {allItems.length} de {totalItems} registros
diff --git a/frontend/src/routes/dashboard/general_catalogs/units_of_measure/general/+page.svelte b/frontend/src/routes/dashboard/general_catalogs/units_of_measure/general/+page.svelte index 92a5cdd1..00f06498 100644 --- a/frontend/src/routes/dashboard/general_catalogs/units_of_measure/general/+page.svelte +++ b/frontend/src/routes/dashboard/general_catalogs/units_of_measure/general/+page.svelte @@ -3,18 +3,22 @@ import { goto } from '$app/navigation'; import { browser } from '$app/environment'; import { createColumns } from '$lib/components/dashboard/general_catalogs/units_of_measure/general/columns'; - import DataTable from '$lib/components/dashboard/general_catalogs/units_of_measure/general/data-table.svelte'; + import InfiniteDataTable from '$lib/components/dashboard/common/infinite-data-table.svelte'; import CreateEditDialog from '$lib/components/dashboard/general_catalogs/units_of_measure/general/create-edit-dialog.svelte'; + import * as Card from '$lib/components/ui/card'; import { Button } from '$lib/components/ui/button'; import { Input } from '$lib/components/ui/input'; - import { Plus } from 'lucide-svelte'; + import { Plus, RefreshCw } from 'lucide-svelte'; import type { PageData } from './$types'; import { useShortcuts } from '$lib/hooks/use-shortcuts'; import { obtenerAtajosListaUnidadesGeneral } from '$lib/config/shortcuts/dashboard/general_catalogs/units_of_measure/general/list'; + import { getUnitsOfMeasureGeneral } from '$lib/api/dashboard/a76/general_catalogs/units-of-measure'; + import { companyStore } from '$lib/stores/company.svelte'; let { data }: { data: PageData } = $props(); let createDialogOpen = $state(false); + let error = $state(data.error || null); // Atajos useShortcuts( @@ -30,10 +34,52 @@ let searchDesc = $state($page.url.searchParams.get('description') || ''); let timeout: ReturnType; - function handleSearch() { + let allItems = $state(data.general_units?.items || []); + let currentPage = $state(data.general_units?.page || 1); + let pageSize = $state(data.general_units?.page_size || 50); + let totalItems = $state(data.general_units?.total || 0); + let loading = $state(false); + let hasMore = $derived(allItems.length < totalItems); + + $effect(() => { + if (data.general_units) { + allItems = data.general_units.items || []; + currentPage = data.general_units.page || 1; + totalItems = data.general_units.total || 0; + pageSize = data.general_units.page_size || pageSize; + } + }); + + async function handleSearch() { if (!browser) return; clearTimeout(timeout); - timeout = setTimeout(() => { + timeout = setTimeout(async () => { + if (!companyStore.activeCompany) return; + loading = true; + error = null; + try { + const filters: Record = {}; + if (searchCode) filters.code = searchCode; + if (searchDesc) filters.description = searchDesc; + + const response = await getUnitsOfMeasureGeneral( + 1, + pageSize, + companyStore.activeCompany.id, + filters + ); + if (response.data) { + allItems = response.data.items; + currentPage = 1; + totalItems = response.data.total; + } + } catch (err) { + error = 'Error aplicando filtros'; + console.error('Error applying filters:', err); + } finally { + loading = false; + } + const url = new URL($page.url); if (searchCode) url.searchParams.set('code', searchCode); else url.searchParams.delete('code'); @@ -41,50 +87,92 @@ if (searchDesc) url.searchParams.set('description', searchDesc); else url.searchParams.delete('description'); - url.searchParams.set('page', '1'); - goto(url, { keepFocus: true, noScroll: true }); + history.replaceState(history.state, '', url); }, 500); } + async function loadMore() { + if (loading || !hasMore || !companyStore.activeCompany) return; + loading = true; + error = null; + try { + const filters: Record = {}; + if (searchCode) filters.code = searchCode; + if (searchDesc) filters.description = searchDesc; + + const response = await getUnitsOfMeasureGeneral( + currentPage + 1, + pageSize, + companyStore.activeCompany.id, + filters + ); + if (response.data?.items) { + allItems = [...allItems, ...response.data.items]; + currentPage += 1; + totalItems = response.data.total; + } + } catch (err) { + error = 'Error cargando mas datos'; + console.error('Error loading more general units:', err); + } finally { + loading = false; + } + } + + async function reloadData() { + if (!companyStore.activeCompany) return; + loading = true; + error = null; + try { + const filters: Record = {}; + if (searchCode) filters.code = searchCode; + if (searchDesc) filters.description = searchDesc; + + const response = await getUnitsOfMeasureGeneral( + 1, + pageSize, + companyStore.activeCompany.id, + filters + ); + if (response.data) { + allItems = response.data.items; + currentPage = 1; + totalItems = response.data.total; + } + } catch (err) { + error = 'Error al recargar datos'; + console.error('Error reloading general units:', err); + } finally { + loading = false; + } + } + function handleSuccess() { - const url = new URL($page.url); - goto(url, { invalidateAll: true }); + reloadData(); } -
+

Unidades de Medida

Catálogo general de unidades de medida

- +
-
-
- + {#if error} +
+ {error}
-
- -
-
+ {/if} -
- -
+ +
Listado de Unidades
+
+
+ +
Mostrando {allItems.length} de {totalItems} registros
diff --git a/frontend/src/routes/dashboard/general_catalogs/units_of_measure/oma/+page.svelte b/frontend/src/routes/dashboard/general_catalogs/units_of_measure/oma/+page.svelte index eab0d9a6..da28b5ba 100644 --- a/frontend/src/routes/dashboard/general_catalogs/units_of_measure/oma/+page.svelte +++ b/frontend/src/routes/dashboard/general_catalogs/units_of_measure/oma/+page.svelte @@ -3,18 +3,22 @@ import { goto } from '$app/navigation'; import { browser } from '$app/environment'; import { createColumns } from '$lib/components/dashboard/general_catalogs/units_of_measure/oma/columns'; - import DataTable from '$lib/components/dashboard/general_catalogs/units_of_measure/oma/data-table.svelte'; + import InfiniteDataTable from '$lib/components/dashboard/common/infinite-data-table.svelte'; import CreateEditDialog from '$lib/components/dashboard/general_catalogs/units_of_measure/oma/create-edit-dialog.svelte'; + import * as Card from '$lib/components/ui/card'; import { Button } from '$lib/components/ui/button'; import { Input } from '$lib/components/ui/input'; - import { Plus } from 'lucide-svelte'; + import { Plus, RefreshCw } from 'lucide-svelte'; import type { PageData } from './$types'; import { useShortcuts } from '$lib/hooks/use-shortcuts'; import { obtenerAtajosListaUnidadesOMA } from '$lib/config/shortcuts/dashboard/general_catalogs/units_of_measure/oma/list'; + import { getUnitsOfMeasureOMA } from '$lib/api/dashboard/a76/general_catalogs/units-of-measure'; + import { companyStore } from '$lib/stores/company.svelte'; let { data }: { data: PageData } = $props(); let createDialogOpen = $state(false); + let error = $state(data.error || null); // Atajos useShortcuts( @@ -30,10 +34,52 @@ let searchDesc = $state($page.url.searchParams.get('description') || ''); let timeout: ReturnType; - function handleSearch() { + let allItems = $state(data.oma_units?.items || []); + let currentPage = $state(data.oma_units?.page || 1); + let pageSize = $state(data.oma_units?.page_size || 50); + let totalItems = $state(data.oma_units?.total || 0); + let loading = $state(false); + let hasMore = $derived(allItems.length < totalItems); + + $effect(() => { + if (data.oma_units) { + allItems = data.oma_units.items || []; + currentPage = data.oma_units.page || 1; + totalItems = data.oma_units.total || 0; + pageSize = data.oma_units.page_size || pageSize; + } + }); + + async function handleSearch() { if (!browser) return; clearTimeout(timeout); - timeout = setTimeout(() => { + timeout = setTimeout(async () => { + if (!companyStore.activeCompany) return; + loading = true; + error = null; + try { + const filters: Record = {}; + if (searchCode) filters.code = searchCode; + if (searchDesc) filters.description = searchDesc; + + const response = await getUnitsOfMeasureOMA( + 1, + pageSize, + companyStore.activeCompany.id, + filters + ); + if (response.data) { + allItems = response.data.items; + currentPage = 1; + totalItems = response.data.total; + } + } catch (err) { + error = 'Error aplicando filtros'; + console.error('Error applying filters:', err); + } finally { + loading = false; + } + const url = new URL($page.url); if (searchCode) url.searchParams.set('code', searchCode); else url.searchParams.delete('code'); @@ -41,50 +87,92 @@ if (searchDesc) url.searchParams.set('description', searchDesc); else url.searchParams.delete('description'); - url.searchParams.set('page', '1'); - goto(url, { keepFocus: true, noScroll: true }); + history.replaceState(history.state, '', url); }, 500); } + async function loadMore() { + if (loading || !hasMore || !companyStore.activeCompany) return; + loading = true; + error = null; + try { + const filters: Record = {}; + if (searchCode) filters.code = searchCode; + if (searchDesc) filters.description = searchDesc; + + const response = await getUnitsOfMeasureOMA( + currentPage + 1, + pageSize, + companyStore.activeCompany.id, + filters + ); + if (response.data?.items) { + allItems = [...allItems, ...response.data.items]; + currentPage += 1; + totalItems = response.data.total; + } + } catch (err) { + error = 'Error cargando mas datos'; + console.error('Error loading more OMA units:', err); + } finally { + loading = false; + } + } + + async function reloadData() { + if (!companyStore.activeCompany) return; + loading = true; + error = null; + try { + const filters: Record = {}; + if (searchCode) filters.code = searchCode; + if (searchDesc) filters.description = searchDesc; + + const response = await getUnitsOfMeasureOMA( + 1, + pageSize, + companyStore.activeCompany.id, + filters + ); + if (response.data) { + allItems = response.data.items; + currentPage = 1; + totalItems = response.data.total; + } + } catch (err) { + error = 'Error al recargar datos'; + console.error('Error reloading OMA units:', err); + } finally { + loading = false; + } + } + function handleSuccess() { - const url = new URL($page.url); - goto(url, { invalidateAll: true }); + reloadData(); } -
+

Unidades de Medida OMA

Catálogo de unidades de medida OMA

- +
-
-
- + {#if error} +
+ {error}
-
- -
-
+ {/if} -
- -
+ +
Listado de Unidades OMA
+
+
+ +
Mostrando {allItems.length} de {totalItems} registros
diff --git a/frontend/src/routes/dashboard/general_catalogs/vehicles/+page.svelte b/frontend/src/routes/dashboard/general_catalogs/vehicles/+page.svelte index 1bcc8916..39ee3719 100644 --- a/frontend/src/routes/dashboard/general_catalogs/vehicles/+page.svelte +++ b/frontend/src/routes/dashboard/general_catalogs/vehicles/+page.svelte @@ -1,12 +1,13 @@ -
+
-

Vehículos (Transporte)

+

Vehículos (Transporte)

Gestión del catálogo de camiones y vehículos de transporte

- +
-
- - -
+ +
Listado de Vehículos
+ {#if loading && data.length === 0}
Cargando vehículos...
{:else}
{/if}
+
- {#if loading && data.length === 0} -
- Cargando vehículos... -
- {:else} - - {/if} +
Mostrando {data.length} de {totalItems} registros
diff --git a/frontend/src/routes/dashboard/goods/fixed-asset-classes/+page.svelte b/frontend/src/routes/dashboard/goods/fixed-asset-classes/+page.svelte index 3b9bf873..7f46bab4 100644 --- a/frontend/src/routes/dashboard/goods/fixed-asset-classes/+page.svelte +++ b/frontend/src/routes/dashboard/goods/fixed-asset-classes/+page.svelte @@ -233,19 +233,30 @@ ]); -
- -
-

CATALOGO DE CLASES DE ACTIVO FIJO

-

Gestiona y consulta las clases de activo fijo

+
+
+
+

Clases de Activo Fijo

+

Gestiona y consulta las clases de activo fijo

+
+
+ + +
-
+
-
+
-
+

Filtros

@@ -256,37 +267,37 @@
- +
- +
- +
-
-
+
+

Listado de Clases

Mostrando de {filteredClasses.length} registros - @@ -309,9 +320,7 @@
-
+

Código de Clase @@ -382,6 +391,8 @@

+
+
-
- -
-

CATÁLOGO DE PARTES

-

- Gestiona y consulta las partes de inventario y activo fijo -

+
+
+
+

Catálogo de Partes

+

+ Gestiona y consulta las partes de inventario y activo fijo +

+
+
+ + +
-
+
-
+
-
+

Filtros

@@ -215,23 +226,23 @@
- +
- +
- +
@@ -267,14 +278,14 @@
-
-
+
+

Listado de Partes

Mostrando {filteredParts.length} registros - @@ -298,9 +309,7 @@
-
+

Número de Parte @@ -414,6 +423,8 @@

+
+
-
+
-

Facturas

+

Facturas

Gestiona las facturas del sistema

{#each invoiceTypeOptions() as option} @@ -914,32 +914,29 @@ {/if} - +
Listado de Facturas - - Mostrando {allItems.length} de {totalItems} registros -
-
- - (sorting = newSorting)} - /> + +
+ (sorting = newSorting)} + /> +
+
+ Mostrando {allItems.length} de {totalItems} registros + + Filtros activos: {Object.values(filters).filter((value) => value !== '').length} +
+ +
+ -
+
-

Pedimentos

+

Pedimentos

Gestiona los pedimentos del sistema

@@ -451,7 +451,7 @@ let filters = $state({ id="filter-status" bind:value={filters.status} onchange={applyFilters} - class="flex h-9 w-[220px] rounded-md border border-input bg-background px-3 py-1 text-sm shadow-sm ring-offset-background focus-visible:ring-2 focus-visible:ring-ring focus-visible:outline-none" + class="flex h-9 w-[220px] rounded-md border border-input bg-card px-3 py-1 text-sm shadow-sm ring-offset-background focus-visible:ring-2 focus-visible:ring-ring focus-visible:outline-none" title="Estado" > {#each statusOptions as option} @@ -478,14 +478,11 @@ let filters = $state({ {/if} - +
Listado de Pedimentos - - Mostrando {allItems.length} de {totalItems} registros -
- + - (sorting = newSorting)} - /> +
+ (sorting = newSorting)} + /> +
+
+ Mostrando {allItems.length} de {totalItems} registros + + Filtros activos: {Object.values(filters).filter((value) => value !== '').length} +
+ +
+
-

+

Pedimento - Regímenes

@@ -132,33 +133,16 @@

- -
-
- Búsqueda General - -
-
- {#if error}
{error}
{/if} - -
- -
+ +
Listado de Pedimento - Regímenes
+
+
+ +
Mostrando {allItems.length} de {totalItems} registros
diff --git a/frontend/src/routes/dashboard/reference_data/containers/+page.svelte b/frontend/src/routes/dashboard/reference_data/containers/+page.svelte index 0747b0f9..f25afd54 100644 --- a/frontend/src/routes/dashboard/reference_data/containers/+page.svelte +++ b/frontend/src/routes/dashboard/reference_data/containers/+page.svelte @@ -3,6 +3,7 @@ import { containersApi, type Container } from '$lib/api/dashboard/reference_data/containers'; import DataTable from '$lib/components/dashboard/reference_data/containers/data-table.svelte'; import { createColumns } from '$lib/components/dashboard/reference_data/containers/columns.js'; + import * as Card from '$lib/components/ui/card'; import { Button } from '$lib/components/ui/button'; import { Input } from '$lib/components/ui/input'; import { page } from '$app/stores'; @@ -112,7 +113,7 @@
-

+

Contenedores

@@ -127,27 +128,23 @@

- -
-
- Búsqueda General - -
-
- {#if error}
{error}
{/if} - -
- -
+ + +
+ Listado de Contenedores +
+ +
+
+
+
+
+ +
Mostrando {allItems.length} de {totalItems} registros
diff --git a/frontend/src/routes/dashboard/reference_data/countries/+page.svelte b/frontend/src/routes/dashboard/reference_data/countries/+page.svelte index eb7b9999..378f0264 100644 --- a/frontend/src/routes/dashboard/reference_data/countries/+page.svelte +++ b/frontend/src/routes/dashboard/reference_data/countries/+page.svelte @@ -3,6 +3,7 @@ import { countriesApi, type Country } from '$lib/api/dashboard/reference_data/countries'; import DataTable from '$lib/components/dashboard/reference_data/countries/data-table.svelte'; import { createColumns } from '$lib/components/dashboard/reference_data/countries/columns.js'; + import * as Card from '$lib/components/ui/card'; import { Button } from '$lib/components/ui/button'; import { Input } from '$lib/components/ui/input'; import { RefreshCw } from 'lucide-svelte'; @@ -149,7 +150,7 @@
-

+

Países

@@ -164,33 +165,16 @@

- -
-
- Búsqueda General - -
-
- {#if error}
{error}
{/if} - -
- -
+ +
Listado de Países
+
+
+ +
Mostrando {allItems.length} de {totalItems} registros
diff --git a/frontend/src/routes/dashboard/reference_data/currency_types/+page.svelte b/frontend/src/routes/dashboard/reference_data/currency_types/+page.svelte index ee9ee8ef..50b1085f 100644 --- a/frontend/src/routes/dashboard/reference_data/currency_types/+page.svelte +++ b/frontend/src/routes/dashboard/reference_data/currency_types/+page.svelte @@ -3,6 +3,7 @@ import { currencyTypesApi, type CurrencyType } from '$lib/api/dashboard/reference_data/currency_types'; import DataTable from '$lib/components/dashboard/reference_data/currency_types/data-table.svelte'; import { createColumns } from '$lib/components/dashboard/reference_data/currency_types/columns.js'; + import * as Card from '$lib/components/ui/card'; import { Button } from '$lib/components/ui/button'; import { Input } from '$lib/components/ui/input'; import { page } from '$app/stores'; @@ -112,7 +113,7 @@
-

+

Tipos de Moneda

@@ -127,27 +128,16 @@

- -
-
- Búsqueda General - -
-
- {#if error}
{error}
{/if} - -
- -
+ +
Listado de Tipos de Moneda
+
+
+ +
Mostrando {allItems.length} de {totalItems} registros
diff --git a/frontend/src/routes/dashboard/reference_data/customs_sections/+page.svelte b/frontend/src/routes/dashboard/reference_data/customs_sections/+page.svelte index 16273e5e..2a6da5e7 100644 --- a/frontend/src/routes/dashboard/reference_data/customs_sections/+page.svelte +++ b/frontend/src/routes/dashboard/reference_data/customs_sections/+page.svelte @@ -3,6 +3,7 @@ import { customsSectionsApi, type CustomsSection } from '$lib/api/dashboard/reference_data/customs_sections'; import DataTable from '$lib/components/dashboard/reference_data/customs_sections/data-table.svelte'; import { createColumns } from '$lib/components/dashboard/reference_data/customs_sections/columns.js'; + import * as Card from '$lib/components/ui/card'; import { Button } from '$lib/components/ui/button'; import { Input } from '$lib/components/ui/input'; import { page } from '$app/stores'; @@ -112,7 +113,7 @@
-

+

Secciones Aduanales

@@ -127,27 +128,16 @@

- -
-
- Búsqueda General - -
-
- {#if error}
{error}
{/if} - -
- -
+ +
Listado de Secciones Aduanales
+
+
+ +
Mostrando {allItems.length} de {totalItems} registros
diff --git a/frontend/src/routes/dashboard/reference_data/customs_warehouses/+page.svelte b/frontend/src/routes/dashboard/reference_data/customs_warehouses/+page.svelte index da44fb5c..649546c2 100644 --- a/frontend/src/routes/dashboard/reference_data/customs_warehouses/+page.svelte +++ b/frontend/src/routes/dashboard/reference_data/customs_warehouses/+page.svelte @@ -3,6 +3,7 @@ import { customsWarehousesApi, type CustomsWarehouse } from '$lib/api/dashboard/reference_data/customs_warehouses'; import DataTable from '$lib/components/dashboard/reference_data/customs_warehouses/data-table.svelte'; import { createColumns } from '$lib/components/dashboard/reference_data/customs_warehouses/columns.js'; + import * as Card from '$lib/components/ui/card'; import { Button } from '$lib/components/ui/button'; import { Input } from '$lib/components/ui/input'; import { page } from '$app/stores'; @@ -112,7 +113,7 @@
-

+

Recintos Fiscalizados

@@ -127,27 +128,16 @@

- -
-
- Búsqueda General - -
-
- {#if error}
{error}
{/if} - -
- -
+ +
Listado de Recintos Fiscalizados
+
+
+ +
Mostrando {allItems.length} de {totalItems} registros
diff --git a/frontend/src/routes/dashboard/reference_data/incoterms/+page.svelte b/frontend/src/routes/dashboard/reference_data/incoterms/+page.svelte index c146aa14..5288a8a8 100644 --- a/frontend/src/routes/dashboard/reference_data/incoterms/+page.svelte +++ b/frontend/src/routes/dashboard/reference_data/incoterms/+page.svelte @@ -5,6 +5,7 @@ import { incotermsApi, type Incoterm } from '$lib/api/dashboard/reference_data/incoterms'; import { createColumns } from '$lib/components/dashboard/reference_data/incoterms/columns'; import DataTable from '$lib/components/dashboard/reference_data/incoterms/data-table.svelte'; + import * as Card from '$lib/components/ui/card'; import { Button } from '$lib/components/ui/button'; import { Input } from '$lib/components/ui/input'; import { RefreshCw, Plus } from 'lucide-svelte'; @@ -116,7 +117,7 @@
-

+

Incoterms

@@ -131,42 +132,24 @@

- -
-
- Clave - -
-
- Descripción - -
-
- {#if error}
{error}
{/if} - -
- -
+ + +
+ Listado de Incoterms +
+ + +
+
+
+
+
+ +
Mostrando {allItems.length} de {totalItems} registros
diff --git a/frontend/src/routes/dashboard/reference_data/invoice_types/+page.svelte b/frontend/src/routes/dashboard/reference_data/invoice_types/+page.svelte index 825081e0..9467a74a 100644 --- a/frontend/src/routes/dashboard/reference_data/invoice_types/+page.svelte +++ b/frontend/src/routes/dashboard/reference_data/invoice_types/+page.svelte @@ -3,6 +3,7 @@ import { invoiceTypesApi, type InvoiceType } from '$lib/api/dashboard/reference_data/invoice_types'; import DataTable from '$lib/components/dashboard/reference_data/invoice_types/data-table.svelte'; import { createColumns } from '$lib/components/dashboard/reference_data/invoice_types/columns.js'; + import * as Card from '$lib/components/ui/card'; import { Button } from '$lib/components/ui/button'; import { Input } from '$lib/components/ui/input'; import { page } from '$app/stores'; @@ -112,7 +113,7 @@
-

+

Tipos de Factura

@@ -127,27 +128,16 @@

- -
-
- Búsqueda General - -
-
- {#if error}
{error}
{/if} - -
- -
+ +
Listado de Tipos de Factura
+
+
+ +
Mostrando {allItems.length} de {totalItems} registros
diff --git a/frontend/src/routes/dashboard/reference_data/material_types/+page.svelte b/frontend/src/routes/dashboard/reference_data/material_types/+page.svelte index aecef109..b77a5332 100644 --- a/frontend/src/routes/dashboard/reference_data/material_types/+page.svelte +++ b/frontend/src/routes/dashboard/reference_data/material_types/+page.svelte @@ -3,6 +3,7 @@ import { materialTypesApi, type MaterialType } from '$lib/api/dashboard/reference_data/material_types'; import DataTable from '$lib/components/dashboard/reference_data/material_types/data-table.svelte'; import { createColumns } from '$lib/components/dashboard/reference_data/material_types/columns.js'; + import * as Card from '$lib/components/ui/card'; import { Button } from '$lib/components/ui/button'; import { Input } from '$lib/components/ui/input'; import { page } from '$app/stores'; @@ -112,7 +113,7 @@
-

+

Tipos de Material

@@ -127,27 +128,16 @@

- -
-
- Búsqueda General - -
-
- {#if error}
{error}
{/if} - -
- -
+ +
Listado de Tipos de Material
+
+
+ +
Mostrando {allItems.length} de {totalItems} registros
diff --git a/frontend/src/routes/dashboard/reference_data/payment_methods/+page.svelte b/frontend/src/routes/dashboard/reference_data/payment_methods/+page.svelte index ba845902..54553e47 100644 --- a/frontend/src/routes/dashboard/reference_data/payment_methods/+page.svelte +++ b/frontend/src/routes/dashboard/reference_data/payment_methods/+page.svelte @@ -3,6 +3,7 @@ import { paymentMethodsApi, type PaymentMethod } from '$lib/api/dashboard/reference_data/payment_methods'; import DataTable from '$lib/components/dashboard/reference_data/payment_methods/data-table.svelte'; import { createColumns } from '$lib/components/dashboard/reference_data/payment_methods/columns.js'; + import * as Card from '$lib/components/ui/card'; import { Button } from '$lib/components/ui/button'; import { Input } from '$lib/components/ui/input'; import { page } from '$app/stores'; @@ -112,7 +113,7 @@
-

+

Métodos de Pago

@@ -127,27 +128,16 @@

- -
-
- Búsqueda General - -
-
- {#if error}
{error}
{/if} - -
- -
+ +
Listado de Métodos de Pago
+
+
+ +
Mostrando {allItems.length} de {totalItems} registros
diff --git a/frontend/src/routes/dashboard/reference_data/pedimento_codes/+page.svelte b/frontend/src/routes/dashboard/reference_data/pedimento_codes/+page.svelte index a157eeca..4b763276 100644 --- a/frontend/src/routes/dashboard/reference_data/pedimento_codes/+page.svelte +++ b/frontend/src/routes/dashboard/reference_data/pedimento_codes/+page.svelte @@ -3,6 +3,7 @@ import { pedimentoCodesApi, type PedimentoCode } from '$lib/api/dashboard/reference_data/pedimento_codes'; import DataTable from '$lib/components/dashboard/reference_data/pedimento_codes/data-table.svelte'; import { createColumns } from '$lib/components/dashboard/reference_data/pedimento_codes/columns.js'; + import * as Card from '$lib/components/ui/card'; import { Button } from '$lib/components/ui/button'; import { Input } from '$lib/components/ui/input'; import { page } from '$app/stores'; @@ -112,7 +113,7 @@
-

+

Claves de Pedimento

@@ -127,27 +128,16 @@

- -
-
- Búsqueda General - -
-
- {#if error}
{error}
{/if} - -
- -
+ +
Listado de Claves de Pedimento
+
+
+ +
Mostrando {allItems.length} de {totalItems} registros
diff --git a/frontend/src/routes/dashboard/reference_data/pedimento_regimens/+page.svelte b/frontend/src/routes/dashboard/reference_data/pedimento_regimens/+page.svelte index 050c3433..10256756 100644 --- a/frontend/src/routes/dashboard/reference_data/pedimento_regimens/+page.svelte +++ b/frontend/src/routes/dashboard/reference_data/pedimento_regimens/+page.svelte @@ -3,6 +3,7 @@ import { pedimentoRegimensApi, type PedimentoRegimen } from '$lib/api/dashboard/reference_data/pedimento_regimens'; import DataTable from '$lib/components/dashboard/reference_data/pedimento_regimens/data-table.svelte'; import { createColumns } from '$lib/components/dashboard/reference_data/pedimento_regimens/columns.js'; + import * as Card from '$lib/components/ui/card'; import { Button } from '$lib/components/ui/button'; import { Input } from '$lib/components/ui/input'; import { page } from '$app/stores'; @@ -112,7 +113,7 @@
-

+

Regímenes

@@ -127,27 +128,16 @@

- -
-
- Búsqueda General - -
-
- {#if error}
{error}
{/if} - -
- -
+ +
Listado de Regímenes
+
+
+ +
Mostrando {allItems.length} de {totalItems} registros
diff --git a/frontend/src/routes/dashboard/reference_data/sectors/+page.svelte b/frontend/src/routes/dashboard/reference_data/sectors/+page.svelte index d311ff04..863da60e 100644 --- a/frontend/src/routes/dashboard/reference_data/sectors/+page.svelte +++ b/frontend/src/routes/dashboard/reference_data/sectors/+page.svelte @@ -4,6 +4,7 @@ import { companyStore } from '$lib/stores/company.svelte'; import DataTable from '$lib/components/dashboard/reference_data/sectors/data-table.svelte'; import { createColumns } from '$lib/components/dashboard/reference_data/sectors/columns.js'; + import * as Card from '$lib/components/ui/card'; import { Button } from '$lib/components/ui/button'; import { Input } from '$lib/components/ui/input'; import { page } from '$app/stores'; @@ -136,7 +137,7 @@
-

+

Sectores

@@ -151,27 +152,16 @@

- -
-
- Búsqueda por Clave - -
-
- {#if error}
{error}
{/if} - -
- -
+ +
Listado de Sectores
+
+
+ +
Mostrando {allItems.length} de {totalItems} registros
diff --git a/frontend/src/routes/dashboard/reference_data/states/+page.svelte b/frontend/src/routes/dashboard/reference_data/states/+page.svelte index fc63ced7..9153e117 100644 --- a/frontend/src/routes/dashboard/reference_data/states/+page.svelte +++ b/frontend/src/routes/dashboard/reference_data/states/+page.svelte @@ -3,6 +3,7 @@ import { statesApi, type State } from '$lib/api/dashboard/reference_data/states'; import DataTable from '$lib/components/dashboard/reference_data/states/data-table.svelte'; import { createColumns } from '$lib/components/dashboard/reference_data/states/columns.js'; + import * as Card from '$lib/components/ui/card'; import { Button } from '$lib/components/ui/button'; import { Input } from '$lib/components/ui/input'; import type { PageData } from './$types'; @@ -146,7 +147,7 @@
-

+

Estados

@@ -161,33 +162,16 @@

- -
-
- Búsqueda General - -
-
- {#if error}
{error}
{/if} - -
- -
+ +
Listado de Estados
+
+
+ +
Mostrando {allItems.length} de {totalItems} registros
diff --git a/frontend/src/routes/dashboard/reference_data/transport_modes/+page.svelte b/frontend/src/routes/dashboard/reference_data/transport_modes/+page.svelte index 580a159c..15541683 100644 --- a/frontend/src/routes/dashboard/reference_data/transport_modes/+page.svelte +++ b/frontend/src/routes/dashboard/reference_data/transport_modes/+page.svelte @@ -3,6 +3,7 @@ import { transportModesApi, type TransportMode } from '$lib/api/dashboard/reference_data/transport_modes'; import DataTable from '$lib/components/dashboard/reference_data/transport_modes/data-table.svelte'; import { createColumns } from '$lib/components/dashboard/reference_data/transport_modes/columns.js'; + import * as Card from '$lib/components/ui/card'; import { Button } from '$lib/components/ui/button'; import { Input } from '$lib/components/ui/input'; import { page } from '$app/stores'; @@ -112,7 +113,7 @@
-

+

Modos de Transporte

@@ -127,27 +128,16 @@

- -
-
- Búsqueda General - -
-
- {#if error}
{error}
{/if} - -
- -
+ +
Listado de Modos de Transporte
+
+
+ +
Mostrando {allItems.length} de {totalItems} registros
diff --git a/frontend/src/routes/dashboard/reference_data/transport_types/+page.svelte b/frontend/src/routes/dashboard/reference_data/transport_types/+page.svelte index 1ad8d604..dd9fcc29 100644 --- a/frontend/src/routes/dashboard/reference_data/transport_types/+page.svelte +++ b/frontend/src/routes/dashboard/reference_data/transport_types/+page.svelte @@ -3,6 +3,7 @@ import { transportTypesApi, type TransportType } from '$lib/api/dashboard/reference_data/transport_types'; import DataTable from '$lib/components/dashboard/reference_data/transport_types/data-table.svelte'; import { createColumns } from '$lib/components/dashboard/reference_data/transport_types/columns.js'; + import * as Card from '$lib/components/ui/card'; import { Button } from '$lib/components/ui/button'; import { Input } from '$lib/components/ui/input'; import { page } from '$app/stores'; @@ -112,7 +113,7 @@
-

+

Tipos de Transporte

@@ -127,27 +128,16 @@

- -
-
- Búsqueda General - -
-
- {#if error}
{error}
{/if} - -
- -
+ +
Listado de Tipos de Transporte
+
+
+ +
Mostrando {allItems.length} de {totalItems} registros
diff --git a/frontend/src/routes/dashboard/reference_data/valuation_methods/+page.svelte b/frontend/src/routes/dashboard/reference_data/valuation_methods/+page.svelte index f00f9ca4..03389645 100644 --- a/frontend/src/routes/dashboard/reference_data/valuation_methods/+page.svelte +++ b/frontend/src/routes/dashboard/reference_data/valuation_methods/+page.svelte @@ -3,6 +3,7 @@ import { valuationMethodsApi, type ValuationMethod } from '$lib/api/dashboard/reference_data/valuation_methods'; import DataTable from '$lib/components/dashboard/reference_data/valuation_methods/data-table.svelte'; import { createColumns } from '$lib/components/dashboard/reference_data/valuation_methods/columns.js'; + import * as Card from '$lib/components/ui/card'; import { Button } from '$lib/components/ui/button'; import { Input } from '$lib/components/ui/input'; import { page } from '$app/stores'; @@ -112,7 +113,7 @@
-

+

Métodos de Valoración

@@ -127,27 +128,16 @@

- -
-
- Búsqueda General - -
-
- {#if error}
{error}
{/if} - -
- -
+ +
Listado de Métodos de Valoración
+
+
+ +
Mostrando {allItems.length} de {totalItems} registros