From 0b57742024ae31c6153a0aeb94e6531a01815a44 Mon Sep 17 00:00:00 2001 From: hreyes Date: Fri, 10 Apr 2026 11:08:02 -0600 Subject: [PATCH] feature/catalog-fixed-fix-styles --- .../public/reference_data/incoterms/routes.py | 11 + .../reference_data/code_pedimento_regimens.ts | 17 +- .../dashboard/reference_data/containers.ts | 15 +- .../reference_data/currency_types.ts | 15 +- .../reference_data/customs_sections.ts | 14 +- .../reference_data/customs_warehouses.ts | 15 +- .../api/dashboard/reference_data/incoterms.ts | 15 +- .../dashboard/reference_data/invoice_types.ts | 9 +- .../reference_data/material_types.ts | 9 +- .../reference_data/payment_methods.ts | 15 +- .../reference_data/pedimento_codes.ts | 15 +- .../reference_data/pedimento_regimens.ts | 15 +- .../api/dashboard/reference_data/states.ts | 15 +- .../reference_data/transport_modes.ts | 14 +- .../reference_data/transport_types.ts | 16 +- .../reference_data/valuation_methods.ts | 15 +- .../code_pedimento_regimens/columns.ts | 13 -- .../data-table-actions.svelte | 17 -- .../code_pedimento_regimens/data-table.svelte | 67 +++--- .../containers/data-table-actions.svelte | 17 -- .../containers/data-table.svelte | 67 +++--- .../countries/data-table-actions.svelte | 17 -- .../countries/data-table.svelte | 67 +++--- .../currency_types/data-table-actions.svelte | 17 -- .../currency_types/data-table.svelte | 67 +++--- .../data-table-actions.svelte | 17 -- .../customs_sections/data-table.svelte | 67 +++--- .../data-table-actions.svelte | 17 -- .../customs_warehouses/data-table.svelte | 67 +++--- .../incoterms/data-table-actions.svelte | 17 -- .../incoterms/data-table.svelte | 160 +++++++------- .../invoice_types/data-table-actions.svelte | 17 -- .../invoice_types/data-table.svelte | 67 +++--- .../material_types/data-table-actions.svelte | 17 -- .../material_types/data-table.svelte | 67 +++--- .../payment_methods/data-table-actions.svelte | 17 -- .../payment_methods/data-table.svelte | 67 +++--- .../pedimento_codes/data-table-actions.svelte | 17 -- .../pedimento_codes/data-table.svelte | 67 +++--- .../data-table-actions.svelte | 17 -- .../pedimento_regimens/data-table.svelte | 67 +++--- .../sectors/create-edit-dialog.svelte | 15 +- .../reference_data/sectors/data-table.svelte | 67 +++--- .../sectors/delete-dialog.svelte | 15 +- .../reference_data/states/data-table.svelte | 67 +++--- .../transport_modes/data-table-actions.svelte | 17 -- .../transport_modes/data-table.svelte | 67 +++--- .../transport_types/data-table-actions.svelte | 17 -- .../transport_types/data-table.svelte | 67 +++--- .../data-table-actions.svelte | 17 -- .../valuation_methods/data-table.svelte | 67 +++--- .../ui/sidebar/sidebar-inset.svelte | 2 +- .../ui/sidebar/sidebar-provider.svelte | 2 +- .../reference_data/common/factory.ts | 25 ++- frontend/src/routes/dashboard/+layout.svelte | 2 +- .../routes/dashboard/audit_logs/+page.svelte | 2 +- .../dashboard/audit_logs/bitacora-tab.svelte | 165 ++++++-------- .../dashboard/audit_logs/files-tab.svelte | 89 ++++---- .../dashboard/audit_logs/tasks-tab.svelte | 206 +++++++++-------- .../code_pedimento_regimens/+page.svelte | 174 +++++++-------- .../reference_data/containers/+page.svelte | 181 +++++++-------- .../reference_data/countries/+page.svelte | 87 +++++--- .../currency_types/+page.svelte | 148 ++++++------- .../customs_sections/+page.svelte | 169 ++++++-------- .../customs_warehouses/+page.svelte | 148 ++++++------- .../reference_data/incoterms/+page.server.ts | 11 +- .../reference_data/incoterms/+page.svelte | 135 ++++++++--- .../reference_data/invoice_types/+page.svelte | 150 ++++++------- .../material_types/+page.svelte | 181 +++++++-------- .../payment_methods/+page.svelte | 169 ++++++-------- .../pedimento_codes/+page.svelte | 169 ++++++-------- .../pedimento_regimens/+page.svelte | 169 ++++++-------- .../reference_data/sectors/+page.svelte | 209 +++++++++--------- .../reference_data/states/+page.svelte | 145 ++++++------ .../transport_modes/+page.svelte | 181 +++++++-------- .../transport_types/+page.svelte | 179 +++++++-------- .../valuation_methods/+page.svelte | 150 ++++++------- 77 files changed, 2337 insertions(+), 2666 deletions(-) diff --git a/backend/api/v1/modules/public/reference_data/incoterms/routes.py b/backend/api/v1/modules/public/reference_data/incoterms/routes.py index 02b278fc..261cfddc 100644 --- a/backend/api/v1/modules/public/reference_data/incoterms/routes.py +++ b/backend/api/v1/modules/public/reference_data/incoterms/routes.py @@ -15,11 +15,22 @@ router = APIRouter(prefix="/incoterms") async def list_incoterms( page: int = Query(1, ge=1, description="Número de página"), page_size: int = Query(50, ge=1, le=100, description="Tamaño de página"), + code: str = Query(None, description="Filtrar por clave"), + description: str = Query(None, description="Filtrar por descripción"), db: Session = Depends(get_core_db), current_user: dict = Depends(get_current_user), ): skip = (page - 1) * page_size query = db.query(Incoterm) + + if code: + query = query.filter(Incoterm.code.ilike(f"%{code}%")) + if description: + query = query.filter( + (Incoterm.description_es.ilike(f"%{description}%")) | + (Incoterm.description_en.ilike(f"%{description}%")) + ) + items = query.offset(skip).limit(page_size).all() total = query.count() return { diff --git a/frontend/src/lib/api/dashboard/reference_data/code_pedimento_regimens.ts b/frontend/src/lib/api/dashboard/reference_data/code_pedimento_regimens.ts index 4b927437..7bb4fa45 100644 --- a/frontend/src/lib/api/dashboard/reference_data/code_pedimento_regimens.ts +++ b/frontend/src/lib/api/dashboard/reference_data/code_pedimento_regimens.ts @@ -35,13 +35,18 @@ export interface UpdateCodePedimentoRegimenData { */ export const codePedimentoRegimensApi = { /** - * Lista todos los code pedimento regimens con paginación + * Lista todos los code pedimento regimens con paginación y búsqueda + * @param page - Número de página (por defecto 1) + * @param pageSize - Tamaño de página (por defecto 50) + * @param search - Término de búsqueda (opcional) */ - list: (page = 1, pageSize = 50) => - api.get( - // CORRECTO: Slash antes del signo '?' - `/v1/public/reference_data/code-pedimento-regimens/?page=${page}&page_size=${pageSize}` - ), + list: (page = 1, pageSize = 50, search?: string) => { + let url = `/v1/public/reference_data/code-pedimento-regimens/?page=${page}&page_size=${pageSize}`; + if (search) { + url += `&search=${encodeURIComponent(search)}`; + } + return api.get(url); + }, /** * Obtiene un por ID diff --git a/frontend/src/lib/api/dashboard/reference_data/containers.ts b/frontend/src/lib/api/dashboard/reference_data/containers.ts index 67f240d6..9e4d300b 100644 --- a/frontend/src/lib/api/dashboard/reference_data/containers.ts +++ b/frontend/src/lib/api/dashboard/reference_data/containers.ts @@ -31,15 +31,18 @@ export interface UpdateContainerData { */ export const containersApi = { /** - * Lista todos los containers con paginación + * Lista todos los containers con paginación y búsqueda * @param page - Número de página (por defecto 1) * @param pageSize - Tamaño de página (por defecto 50) + * @param search - Término de búsqueda (opcional) */ - list: (page = 1, pageSize = 50) => - api.get( - // CORRECTO: Slash antes del ? - `/v1/public/reference_data/containers/?page=${page}&page_size=${pageSize}` - ), + list: (page = 1, pageSize = 50, search?: string) => { + let url = `/v1/public/reference_data/containers/?page=${page}&page_size=${pageSize}`; + if (search) { + url += `&search=${encodeURIComponent(search)}`; + } + return api.get(url); + }, /** * Obtiene un container por ID diff --git a/frontend/src/lib/api/dashboard/reference_data/currency_types.ts b/frontend/src/lib/api/dashboard/reference_data/currency_types.ts index 387e1f3f..9199365f 100644 --- a/frontend/src/lib/api/dashboard/reference_data/currency_types.ts +++ b/frontend/src/lib/api/dashboard/reference_data/currency_types.ts @@ -34,15 +34,18 @@ export interface UpdateCurrencyTypeData { */ export const currencyTypesApi = { /** - * Lista todos los tipos de moneda con paginación + * Lista todos los tipos de moneda con paginación y búsqueda * @param page - Número de página (por defecto 1) * @param pageSize - Tamaño de página (por defecto 50) + * @param search - Término de búsqueda (opcional) */ - list: (page = 1, pageSize = 50) => - api.get( - // CORREGIDO: Añadido '/' antes del '?' - `/v1/public/reference_data/currency-types/?page=${page}&page_size=${pageSize}` - ), + list: (page = 1, pageSize = 50, search?: string) => { + let url = `/v1/public/reference_data/currency-types/?page=${page}&page_size=${pageSize}`; + if (search) { + url += `&search=${encodeURIComponent(search)}`; + } + return api.get(url); + }, /** * Obtiene un tipo de moneda por código diff --git a/frontend/src/lib/api/dashboard/reference_data/customs_sections.ts b/frontend/src/lib/api/dashboard/reference_data/customs_sections.ts index e73934d8..e0cafb6e 100644 --- a/frontend/src/lib/api/dashboard/reference_data/customs_sections.ts +++ b/frontend/src/lib/api/dashboard/reference_data/customs_sections.ts @@ -31,14 +31,18 @@ export interface UpdateCustomsSectionData { */ export const customsSectionsApi = { /** - * Lista todas las secciones aduaneras con paginación + * Lista todas las secciones aduaneras con paginación y búsqueda * @param page - Número de página (por defecto 1) * @param pageSize - Tamaño de página (por defecto 50) + * @param search - Término de búsqueda (opcional) */ - list: (page = 1, pageSize = 50) => - api.get( - `/v1/public/reference_data/customs-sections/?page=${page}&page_size=${pageSize}` - ), + list: (page = 1, pageSize = 50, search?: string) => { + let url = `/v1/public/reference_data/customs-sections/?page=${page}&page_size=${pageSize}`; + if (search) { + url += `&search=${encodeURIComponent(search)}`; + } + return api.get(url); + }, /** * Obtiene una sección aduanera por código diff --git a/frontend/src/lib/api/dashboard/reference_data/customs_warehouses.ts b/frontend/src/lib/api/dashboard/reference_data/customs_warehouses.ts index eae2b955..4e90751e 100644 --- a/frontend/src/lib/api/dashboard/reference_data/customs_warehouses.ts +++ b/frontend/src/lib/api/dashboard/reference_data/customs_warehouses.ts @@ -34,15 +34,18 @@ export interface UpdateCustomsWarehouseData { */ export const customsWarehousesApi = { /** - * Lista todos los recintos fiscalizados con paginación + * Lista todos los recintos fiscalizados con paginación y búsqueda * @param page - Número de página (por defecto 1) * @param pageSize - Tamaño de página (por defecto 50) + * @param search - Término de búsqueda (opcional) */ - list: (page = 1, pageSize = 50) => - api.get( - // CORREGIDO: Añadido '/' antes del '?' - `/v1/public/reference_data/customs-warehouses/?page=${page}&page_size=${pageSize}` - ), + list: (page = 1, pageSize = 50, search?: string) => { + let url = `/v1/public/reference_data/customs-warehouses/?page=${page}&page_size=${pageSize}`; + if (search) { + url += `&search=${encodeURIComponent(search)}`; + } + return api.get(url); + }, /** * Obtiene un recinto fiscalizado por clave compuesta (key + customs) diff --git a/frontend/src/lib/api/dashboard/reference_data/incoterms.ts b/frontend/src/lib/api/dashboard/reference_data/incoterms.ts index 2543824e..4e49deb1 100644 --- a/frontend/src/lib/api/dashboard/reference_data/incoterms.ts +++ b/frontend/src/lib/api/dashboard/reference_data/incoterms.ts @@ -34,15 +34,18 @@ export interface UpdateIncotermData { */ export const incotermsApi = { /** - * Lista todos los incoterms con paginación + * Lista todos los incoterms con paginación y filtros * @param page - Número de página (por defecto 1) * @param pageSize - Tamaño de página (por defecto 50) + * @param code - Filtrar por clave (opcional) + * @param description - Filtrar por descripción (opcional) */ - list: (page = 1, pageSize = 50) => - api.get( - // CORREGIDO: Añadido '/' antes del '?' - `/v1/public/reference_data/incoterms/?page=${page}&page_size=${pageSize}` - ), + list: (page = 1, pageSize = 50, code?: string, description?: string) => { + let url = `/v1/public/reference_data/incoterms/?page=${page}&page_size=${pageSize}`; + if (code) url += `&code=${encodeURIComponent(code)}`; + if (description) url += `&description=${encodeURIComponent(description)}`; + return api.get(url); + }, /** * Obtiene un incoterm por código diff --git a/frontend/src/lib/api/dashboard/reference_data/invoice_types.ts b/frontend/src/lib/api/dashboard/reference_data/invoice_types.ts index 87a7c264..91a90ba8 100644 --- a/frontend/src/lib/api/dashboard/reference_data/invoice_types.ts +++ b/frontend/src/lib/api/dashboard/reference_data/invoice_types.ts @@ -38,12 +38,13 @@ export interface UpdateInvoiceTypeData { */ export const invoiceTypesApi = { /** - * Lista todos los tipos de factura con paginación + * Lista todos los tipos de factura con paginación y búsqueda * @param page - Número de página (por defecto 1) * @param pageSize - Tamaño de página (por defecto 50) * @param operation - Filtrar por tipo de operación (imp, exp) + * @param search - Término de búsqueda (opcional) */ - list: (page = 1, pageSize = 50, operation?: string) => { + list: (page = 1, pageSize = 50, operation?: string, search?: string) => { const params = new URLSearchParams({ page: page.toString(), page_size: pageSize.toString() @@ -51,8 +52,10 @@ export const invoiceTypesApi = { if (operation) { params.append('operation', operation); } + if (search) { + params.append('search', search); + } return api.get( - // CORREGIDO: Añadido '/' antes del '?' `/v1/public/reference_data/invoice-types/?${params.toString()}` ); }, diff --git a/frontend/src/lib/api/dashboard/reference_data/material_types.ts b/frontend/src/lib/api/dashboard/reference_data/material_types.ts index d2db1ab3..a4d89267 100644 --- a/frontend/src/lib/api/dashboard/reference_data/material_types.ts +++ b/frontend/src/lib/api/dashboard/reference_data/material_types.ts @@ -34,12 +34,13 @@ */ export const materialTypesApi = { /** - * Lista todos los tipos de material con paginación + * Lista todos los tipos de material con paginación y búsqueda * @param page - Número de página (por defecto 1) * @param pageSize - Tamaño de página (por defecto 50) * @param type - Filtrar por tipo (ACTIVO FIJO, MATERIALES, PRODUCTOS) + * @param search - Término de búsqueda (opcional) */ - list: (page = 1, pageSize = 50, type?: string) => { + list: (page = 1, pageSize = 50, type?: string, search?: string) => { const params = new URLSearchParams({ page: page.toString(), page_size: pageSize.toString() @@ -47,8 +48,10 @@ export const materialTypesApi = { if (type) { params.append('type', type); } + if (search) { + params.append('search', search); + } return api.get( - // CORRECTO: Ya tiene el '/' antes del '?' `/v1/public/reference_data/material-types/?${params.toString()}` ); }, diff --git a/frontend/src/lib/api/dashboard/reference_data/payment_methods.ts b/frontend/src/lib/api/dashboard/reference_data/payment_methods.ts index e0bcbcaf..7253e13b 100644 --- a/frontend/src/lib/api/dashboard/reference_data/payment_methods.ts +++ b/frontend/src/lib/api/dashboard/reference_data/payment_methods.ts @@ -31,15 +31,18 @@ export interface UpdatePaymentMethodData { */ export const paymentMethodsApi = { /** - * Lista todos los métodos de pago con paginación + * Lista todos los métodos de pago con paginación y búsqueda * @param page - Número de página (por defecto 1) * @param pageSize - Tamaño de página (por defecto 50) + * @param search - Término de búsqueda (opcional) */ - list: (page = 1, pageSize = 50) => - api.get( - // CORREGIDO: Añadido '/' antes del '?' - `/v1/public/reference_data/payment-methods/?page=${page}&page_size=${pageSize}` - ), + list: (page = 1, pageSize = 50, search?: string) => { + let url = `/v1/public/reference_data/payment-methods/?page=${page}&page_size=${pageSize}`; + if (search) { + url += `&search=${encodeURIComponent(search)}`; + } + return api.get(url); + }, /** * Obtiene un método de pago por key diff --git a/frontend/src/lib/api/dashboard/reference_data/pedimento_codes.ts b/frontend/src/lib/api/dashboard/reference_data/pedimento_codes.ts index 6a5cb837..5d62d34f 100644 --- a/frontend/src/lib/api/dashboard/reference_data/pedimento_codes.ts +++ b/frontend/src/lib/api/dashboard/reference_data/pedimento_codes.ts @@ -31,15 +31,18 @@ export interface UpdatePedimentoCodeData { */ export const pedimentoCodesApi = { /** - * Lista todas las claves de pedimento con paginación + * Lista todas las claves de pedimento con paginación y búsqueda * @param page - Número de página (por defecto 1) * @param pageSize - Tamaño de página (por defecto 50) + * @param search - Término de búsqueda (opcional) */ - list: (page = 1, pageSize = 50) => - api.get( - // CORREGIDO: Añadido '/' antes del '?' - `/v1/public/reference_data/pedimento-codes/?page=${page}&page_size=${pageSize}` - ), + list: (page = 1, pageSize = 50, search?: string) => { + let url = `/v1/public/reference_data/pedimento-codes/?page=${page}&page_size=${pageSize}`; + if (search) { + url += `&search=${encodeURIComponent(search)}`; + } + return api.get(url); + }, /** * Obtiene una clave de pedimento por code diff --git a/frontend/src/lib/api/dashboard/reference_data/pedimento_regimens.ts b/frontend/src/lib/api/dashboard/reference_data/pedimento_regimens.ts index 9466a70d..124c9a7b 100644 --- a/frontend/src/lib/api/dashboard/reference_data/pedimento_regimens.ts +++ b/frontend/src/lib/api/dashboard/reference_data/pedimento_regimens.ts @@ -31,15 +31,18 @@ export interface UpdatePedimentoRegimenData { */ export const pedimentoRegimensApi = { /** - * Lista todos los regímenes de pedimento con paginación + * Lista todos los regímenes de pedimento con paginación y búsqueda * @param page - Número de página (por defecto 1) * @param pageSize - Tamaño de página (por defecto 50) + * @param search - Término de búsqueda (opcional) */ - list: (page = 1, pageSize = 50) => - api.get( - // CORREGIDO: Añadido '/' antes del '?' - `/v1/public/reference_data/pedimento-regimens/?page=${page}&page_size=${pageSize}` - ), + list: (page = 1, pageSize = 50, search?: string) => { + let url = `/v1/public/reference_data/pedimento-regimens/?page=${page}&page_size=${pageSize}`; + if (search) { + url += `&search=${encodeURIComponent(search)}`; + } + return api.get(url); + }, /** * Obtiene un régimen de pedimento por code diff --git a/frontend/src/lib/api/dashboard/reference_data/states.ts b/frontend/src/lib/api/dashboard/reference_data/states.ts index 93a1db35..f7baf99d 100644 --- a/frontend/src/lib/api/dashboard/reference_data/states.ts +++ b/frontend/src/lib/api/dashboard/reference_data/states.ts @@ -37,15 +37,18 @@ export interface UpdateStateData { */ export const statesApi = { /** - * Lista todos los estados con paginación + * Lista todos los estados con paginación y búsqueda * @param page - Número de página (por defecto 1) * @param pageSize - Tamaño de página (por defecto 50) + * @param search - Término de búsqueda (opcional) */ - list: (page = 1, pageSize = 50) => - api.get( - // CORREGIDO: Añadido '/' antes de '?' - `/v1/public/reference_data/states/?page=${page}&page_size=${pageSize}` - ), + list: (page = 1, pageSize = 50, search?: string) => { + let url = `/v1/public/reference_data/states/?page=${page}&page_size=${pageSize}`; + if (search) { + url += `&search=${encodeURIComponent(search)}`; + } + return api.get(url); + }, /** * Obtiene un estado por m3_key diff --git a/frontend/src/lib/api/dashboard/reference_data/transport_modes.ts b/frontend/src/lib/api/dashboard/reference_data/transport_modes.ts index 5bb23ad9..a16b9a4e 100644 --- a/frontend/src/lib/api/dashboard/reference_data/transport_modes.ts +++ b/frontend/src/lib/api/dashboard/reference_data/transport_modes.ts @@ -31,14 +31,18 @@ export interface UpdateTransportModeData { */ export const transportModesApi = { /** - * Lista todos los modos de transporte con paginación + * Lista todos los modos de transporte con paginación y búsqueda * @param page - Número de página (por defecto 1) * @param pageSize - Tamaño de página (por defecto 50) + * @param search - Término de búsqueda (opcional) */ - list: (page = 1, pageSize = 50) => - api.get( - `/v1/public/reference_data/transport-modes/?page=${page}&page_size=${pageSize}` - ), + list: (page = 1, pageSize = 50, search?: string) => { + let url = `/v1/public/reference_data/transport-modes/?page=${page}&page_size=${pageSize}`; + if (search) { + url += `&search=${encodeURIComponent(search)}`; + } + return api.get(url); + }, /** * Obtiene un modo de transporte por key diff --git a/frontend/src/lib/api/dashboard/reference_data/transport_types.ts b/frontend/src/lib/api/dashboard/reference_data/transport_types.ts index 12b162b1..6b473373 100644 --- a/frontend/src/lib/api/dashboard/reference_data/transport_types.ts +++ b/frontend/src/lib/api/dashboard/reference_data/transport_types.ts @@ -31,12 +31,18 @@ export interface UpdateTransportTypeData { */ export const transportTypesApi = { /** - * Lista todos los tipos de transporte con paginación + * Lista todos los tipos de transporte con paginación y búsqueda + * @param page - Número de página (por defecto 1) + * @param pageSize - Tamaño de página (por defecto 50) + * @param search - Término de búsqueda (opcional) */ - list: (page = 1, pageSize = 50) => - api.get( - `/v1/public/reference_data/transport-types/?page=${page}&page_size=${pageSize}` - ), + list: (page = 1, pageSize = 50, search?: string) => { + let url = `/v1/public/reference_data/transport-types/?page=${page}&page_size=${pageSize}`; + if (search) { + url += `&search=${encodeURIComponent(search)}`; + } + return api.get(url); + }, /** * Obtiene un tipo de transporte por transport_code diff --git a/frontend/src/lib/api/dashboard/reference_data/valuation_methods.ts b/frontend/src/lib/api/dashboard/reference_data/valuation_methods.ts index df4a320c..6f3badb8 100644 --- a/frontend/src/lib/api/dashboard/reference_data/valuation_methods.ts +++ b/frontend/src/lib/api/dashboard/reference_data/valuation_methods.ts @@ -31,15 +31,18 @@ export interface UpdateValuationMethodData { */ export const valuationMethodsApi = { /** - * Lista todos los métodos de valoración con paginación + * Lista todos los métodos de valoración con paginación y búsqueda * @param page - Número de página (por defecto 1) * @param pageSize - Tamaño de página (por defecto 50) + * @param search - Término de búsqueda (opcional) */ - list: (page = 1, pageSize = 50) => - api.get( - // CORREGIDO: Añadido '/' antes del '?' - `/v1/public/reference_data/valuation-methods/?page=${page}&page_size=${pageSize}` - ), + list: (page = 1, pageSize = 50, search?: string) => { + let url = `/v1/public/reference_data/valuation-methods/?page=${page}&page_size=${pageSize}`; + if (search) { + url += `&search=${encodeURIComponent(search)}`; + } + return api.get(url); + }, /** * Obtiene un método de valoración por key diff --git a/frontend/src/lib/components/dashboard/reference_data/code_pedimento_regimens/columns.ts b/frontend/src/lib/components/dashboard/reference_data/code_pedimento_regimens/columns.ts index 41ae7ce2..065745f5 100644 --- a/frontend/src/lib/components/dashboard/reference_data/code_pedimento_regimens/columns.ts +++ b/frontend/src/lib/components/dashboard/reference_data/code_pedimento_regimens/columns.ts @@ -12,19 +12,6 @@ export type CodePedimentoRegimen = { export function createColumns(onSuccess?: () => void): ColumnDef[] { return [ - { - accessorKey: "id", - header: "ID", - cell: ({ row }) => { - const idSnippet = createRawSnippet<[{ id: number }]>((getId) => { - const { id } = getId(); - return { - render: () => `
${id}
` - }; - }); - return renderSnippet(idSnippet, { id: row.original.id }); - } - }, { accessorKey: "pedimento_code", header: "Código Pedimento", diff --git a/frontend/src/lib/components/dashboard/reference_data/code_pedimento_regimens/data-table-actions.svelte b/frontend/src/lib/components/dashboard/reference_data/code_pedimento_regimens/data-table-actions.svelte index 18c91f2d..faa561f9 100644 --- a/frontend/src/lib/components/dashboard/reference_data/code_pedimento_regimens/data-table-actions.svelte +++ b/frontend/src/lib/components/dashboard/reference_data/code_pedimento_regimens/data-table-actions.svelte @@ -3,9 +3,7 @@ import { Button } from "$lib/components/ui/button/index.js"; import * as DropdownMenu from "$lib/components/ui/dropdown-menu/index.js"; import type { CodePedimentoRegimen } from "./columns.js"; - import CreateEditDialog from "./create-edit-dialog.svelte"; import DetailsDialog from "./details-dialog.svelte"; - import DeleteDialog from "./delete-dialog.svelte"; let { item, @@ -16,8 +14,6 @@ } = $props(); let showDetailsDialog = $state(false); - let showEditDialog = $state(false); - let showDeleteDialog = $state(false); function handleCopyId() { navigator.clipboard.writeText(item.id.toString()); @@ -26,14 +22,6 @@ function handleViewDetails() { showDetailsDialog = true; } - - function handleEdit() { - showEditDialog = true; - } - - function handleDelete() { - showDeleteDialog = true; - } @@ -54,13 +42,8 @@ Ver detalles - Editar - - Eliminar - - 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 2f4a88e7..4109783b 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 @@ -59,68 +59,67 @@ }); -
-
- - +
+
+ + {#each table.getHeaderGroups() as headerGroup (headerGroup.id)} - + {#each headerGroup.headers as header (header.id)} - + {/each} - + {/each} - - + + {#each table.getRowModel().rows as row (row.id)} - + {#each row.getVisibleCells() as cell (cell.id)} - + {/each} - + {:else} - - + + + {/each} - + {#if hasMore} - - -
+
+ + {/if} - - + +
{#if !header.isPlaceholder} {/if} - +
- +
No hay resultados. - - +
+
{#if loading} -
-
- Cargando más... +
+
+ Cargando más registros...
{:else} -
- Desplázate para cargar más +
+ + Desplázate para cargar más +
{/if}
- - +
diff --git a/frontend/src/lib/components/dashboard/reference_data/containers/data-table-actions.svelte b/frontend/src/lib/components/dashboard/reference_data/containers/data-table-actions.svelte index 07f22b3b..9689ba27 100644 --- a/frontend/src/lib/components/dashboard/reference_data/containers/data-table-actions.svelte +++ b/frontend/src/lib/components/dashboard/reference_data/containers/data-table-actions.svelte @@ -3,9 +3,7 @@ import { Button } from "$lib/components/ui/button/index.js"; import * as DropdownMenu from "$lib/components/ui/dropdown-menu/index.js"; import type { Container } from "./columns.js"; - import CreateEditDialog from "./create-edit-dialog.svelte"; import DetailsDialog from "./details-dialog.svelte"; - import DeleteDialog from "./delete-dialog.svelte"; let { item, @@ -16,8 +14,6 @@ } = $props(); let showDetailsDialog = $state(false); - let showEditDialog = $state(false); - let showDeleteDialog = $state(false); function handleCopyId() { navigator.clipboard.writeText(item.key.toString()); @@ -26,14 +22,6 @@ function handleViewDetails() { showDetailsDialog = true; } - - function handleEdit() { - showEditDialog = true; - } - - function handleDelete() { - showDeleteDialog = true; - } @@ -54,13 +42,8 @@ Ver detalles - Editar - - Eliminar - - 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 2f4a88e7..4109783b 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 @@ -59,68 +59,67 @@ }); -
-
- - +
+
+ + {#each table.getHeaderGroups() as headerGroup (headerGroup.id)} - + {#each headerGroup.headers as header (header.id)} - + {/each} - + {/each} - - + + {#each table.getRowModel().rows as row (row.id)} - + {#each row.getVisibleCells() as cell (cell.id)} - + {/each} - + {:else} - - + + + {/each} - + {#if hasMore} - - -
+
+ + {/if} - - + +
{#if !header.isPlaceholder} {/if} - +
- +
No hay resultados. - - +
+
{#if loading} -
-
- Cargando más... +
+
+ Cargando más registros...
{:else} -
- Desplázate para cargar más +
+ + Desplázate para cargar más +
{/if}
- - +
diff --git a/frontend/src/lib/components/dashboard/reference_data/countries/data-table-actions.svelte b/frontend/src/lib/components/dashboard/reference_data/countries/data-table-actions.svelte index cd8ee7db..fce57c19 100644 --- a/frontend/src/lib/components/dashboard/reference_data/countries/data-table-actions.svelte +++ b/frontend/src/lib/components/dashboard/reference_data/countries/data-table-actions.svelte @@ -3,9 +3,7 @@ import { Button } from "$lib/components/ui/button/index.js"; import * as DropdownMenu from "$lib/components/ui/dropdown-menu/index.js"; import type { Country } from "./columns.js"; - import CreateEditDialog from "./create-edit-dialog.svelte"; import DetailsDialog from "./details-dialog.svelte"; - import DeleteDialog from "./delete-dialog.svelte"; let { item, @@ -16,8 +14,6 @@ } = $props(); let showDetailsDialog = $state(false); - let showEditDialog = $state(false); - let showDeleteDialog = $state(false); function handleCopyId() { navigator.clipboard.writeText(item.m3_key.toString()); @@ -26,14 +22,6 @@ function handleViewDetails() { showDetailsDialog = true; } - - function handleEdit() { - showEditDialog = true; - } - - function handleDelete() { - showDeleteDialog = true; - } @@ -54,13 +42,8 @@ Ver detalles - Editar - - Eliminar - - 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 2f4a88e7..4109783b 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 @@ -59,68 +59,67 @@ }); -
-
- - +
+
+ + {#each table.getHeaderGroups() as headerGroup (headerGroup.id)} - + {#each headerGroup.headers as header (header.id)} - + {/each} - + {/each} - - + + {#each table.getRowModel().rows as row (row.id)} - + {#each row.getVisibleCells() as cell (cell.id)} - + {/each} - + {:else} - - + + + {/each} - + {#if hasMore} - - -
+
+ + {/if} - - + +
{#if !header.isPlaceholder} {/if} - +
- +
No hay resultados. - - +
+
{#if loading} -
-
- Cargando más... +
+
+ Cargando más registros...
{:else} -
- Desplázate para cargar más +
+ + Desplázate para cargar más +
{/if}
- - +
diff --git a/frontend/src/lib/components/dashboard/reference_data/currency_types/data-table-actions.svelte b/frontend/src/lib/components/dashboard/reference_data/currency_types/data-table-actions.svelte index 63dd58c3..69d90ade 100644 --- a/frontend/src/lib/components/dashboard/reference_data/currency_types/data-table-actions.svelte +++ b/frontend/src/lib/components/dashboard/reference_data/currency_types/data-table-actions.svelte @@ -3,9 +3,7 @@ import { Button } from "$lib/components/ui/button/index.js"; import * as DropdownMenu from "$lib/components/ui/dropdown-menu/index.js"; import type { CurrencyType } from "./columns.js"; - import CreateEditDialog from "./create-edit-dialog.svelte"; import DetailsDialog from "./details-dialog.svelte"; - import DeleteDialog from "./delete-dialog.svelte"; let { item, @@ -16,8 +14,6 @@ } = $props(); let showDetailsDialog = $state(false); - let showEditDialog = $state(false); - let showDeleteDialog = $state(false); function handleCopyId() { navigator.clipboard.writeText(item.code.toString()); @@ -26,14 +22,6 @@ function handleViewDetails() { showDetailsDialog = true; } - - function handleEdit() { - showEditDialog = true; - } - - function handleDelete() { - showDeleteDialog = true; - } @@ -54,13 +42,8 @@ Ver detalles - Editar - - Eliminar - - 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 2f4a88e7..4109783b 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 @@ -59,68 +59,67 @@ }); -
-
- - +
+
+ + {#each table.getHeaderGroups() as headerGroup (headerGroup.id)} - + {#each headerGroup.headers as header (header.id)} - + {/each} - + {/each} - - + + {#each table.getRowModel().rows as row (row.id)} - + {#each row.getVisibleCells() as cell (cell.id)} - + {/each} - + {:else} - - + + + {/each} - + {#if hasMore} - - -
+
+ + {/if} - - + +
{#if !header.isPlaceholder} {/if} - +
- +
No hay resultados. - - +
+
{#if loading} -
-
- Cargando más... +
+
+ Cargando más registros...
{:else} -
- Desplázate para cargar más +
+ + Desplázate para cargar más +
{/if}
- - +
diff --git a/frontend/src/lib/components/dashboard/reference_data/customs_sections/data-table-actions.svelte b/frontend/src/lib/components/dashboard/reference_data/customs_sections/data-table-actions.svelte index 3ffd2ee3..8dcf4a58 100644 --- a/frontend/src/lib/components/dashboard/reference_data/customs_sections/data-table-actions.svelte +++ b/frontend/src/lib/components/dashboard/reference_data/customs_sections/data-table-actions.svelte @@ -3,9 +3,7 @@ import { Button } from "$lib/components/ui/button/index.js"; import * as DropdownMenu from "$lib/components/ui/dropdown-menu/index.js"; import type { CustomsSection } from "./columns.js"; - import CreateEditDialog from "./create-edit-dialog.svelte"; import DetailsDialog from "./details-dialog.svelte"; - import DeleteDialog from "./delete-dialog.svelte"; let { item, @@ -16,8 +14,6 @@ } = $props(); let showDetailsDialog = $state(false); - let showEditDialog = $state(false); - let showDeleteDialog = $state(false); function handleCopyId() { navigator.clipboard.writeText(item.customs_code.toString()); @@ -26,14 +22,6 @@ function handleViewDetails() { showDetailsDialog = true; } - - function handleEdit() { - showEditDialog = true; - } - - function handleDelete() { - showDeleteDialog = true; - } @@ -54,13 +42,8 @@ Ver detalles - Editar - - Eliminar - - 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 2f4a88e7..c34967ce 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 @@ -59,68 +59,67 @@ }); -
-
- - +
+
+ + {#each table.getHeaderGroups() as headerGroup (headerGroup.id)} - + {#each headerGroup.headers as header (header.id)} - + {/each} - + {/each} - - + + {#each table.getRowModel().rows as row (row.id)} - + {#each row.getVisibleCells() as cell (cell.id)} - + {/each} - + {:else} - - + + + {/each} - + {#if hasMore} - - -
+
+ + {/if} - - + +
{#if !header.isPlaceholder} {/if} - +
- +
No hay resultados. - - +
+
{#if loading} -
-
- Cargando más... +
+
+ Cargando más registros...
{:else} -
- Desplázate para cargar más +
+ + Desplázate para cargar más +
{/if}
- - +
diff --git a/frontend/src/lib/components/dashboard/reference_data/customs_warehouses/data-table-actions.svelte b/frontend/src/lib/components/dashboard/reference_data/customs_warehouses/data-table-actions.svelte index d204b9c0..3fd6f9fe 100644 --- a/frontend/src/lib/components/dashboard/reference_data/customs_warehouses/data-table-actions.svelte +++ b/frontend/src/lib/components/dashboard/reference_data/customs_warehouses/data-table-actions.svelte @@ -3,9 +3,7 @@ import { Button } from "$lib/components/ui/button/index.js"; import * as DropdownMenu from "$lib/components/ui/dropdown-menu/index.js"; import type { CustomsWarehouse } from "./columns.js"; - import CreateEditDialog from "./create-edit-dialog.svelte"; import DetailsDialog from "./details-dialog.svelte"; - import DeleteDialog from "./delete-dialog.svelte"; let { item, @@ -16,8 +14,6 @@ } = $props(); let showDetailsDialog = $state(false); - let showEditDialog = $state(false); - let showDeleteDialog = $state(false); function handleCopyId() { navigator.clipboard.writeText(`${item.key}|${item.customs}`); @@ -26,14 +22,6 @@ function handleViewDetails() { showDetailsDialog = true; } - - function handleEdit() { - showEditDialog = true; - } - - function handleDelete() { - showDeleteDialog = true; - } @@ -54,13 +42,8 @@ Ver detalles - Editar - - Eliminar - - 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 2f4a88e7..4109783b 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 @@ -59,68 +59,67 @@ }); -
-
- - +
+
+ + {#each table.getHeaderGroups() as headerGroup (headerGroup.id)} - + {#each headerGroup.headers as header (header.id)} - + {/each} - + {/each} - - + + {#each table.getRowModel().rows as row (row.id)} - + {#each row.getVisibleCells() as cell (cell.id)} - + {/each} - + {:else} - - + + + {/each} - + {#if hasMore} - - -
+
+ + {/if} - - + +
{#if !header.isPlaceholder} {/if} - +
- +
No hay resultados. - - +
+
{#if loading} -
-
- Cargando más... +
+
+ Cargando más registros...
{:else} -
- Desplázate para cargar más +
+ + Desplázate para cargar más +
{/if}
- - +
diff --git a/frontend/src/lib/components/dashboard/reference_data/incoterms/data-table-actions.svelte b/frontend/src/lib/components/dashboard/reference_data/incoterms/data-table-actions.svelte index ce9a6cbe..9ea03340 100644 --- a/frontend/src/lib/components/dashboard/reference_data/incoterms/data-table-actions.svelte +++ b/frontend/src/lib/components/dashboard/reference_data/incoterms/data-table-actions.svelte @@ -3,9 +3,7 @@ import { Button } from "$lib/components/ui/button/index.js"; import * as DropdownMenu from "$lib/components/ui/dropdown-menu/index.js"; import type { Incoterm } from "./columns.js"; - import CreateEditDialog from "./create-edit-dialog.svelte"; import DetailsDialog from "./details-dialog.svelte"; - import DeleteDialog from "./delete-dialog.svelte"; let { item, @@ -16,8 +14,6 @@ } = $props(); let showDetailsDialog = $state(false); - let showEditDialog = $state(false); - let showDeleteDialog = $state(false); function handleCopyId() { navigator.clipboard.writeText(item.code.toString()); @@ -26,14 +22,6 @@ function handleViewDetails() { showDetailsDialog = true; } - - function handleEdit() { - showEditDialog = true; - } - - function handleDelete() { - showDeleteDialog = true; - } @@ -54,13 +42,8 @@ Ver detalles - Editar - - Eliminar - - 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 3d5b2a66..dd73a894 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 @@ -3,104 +3,114 @@ type ColumnDef, getCoreRowModel } from "@tanstack/table-core"; + import { onMount } from "svelte"; import { createSvelteTable, FlexRender } from "$lib/components/ui/data-table/index.js"; import * as Table from "$lib/components/ui/table/index.js"; import { Button } from "$lib/components/ui/button"; - import { goto } from "$app/navigation"; - import { page } from "$app/stores"; type DataTableProps = { columns: ColumnDef[]; data: TData[]; - pageCount: number; - totalItems: number; + loading: boolean; + hasMore: boolean; + loadMore: () => void; }; let { data, columns, - pageCount, - totalItems + loading, + hasMore, + loadMore }: DataTableProps = $props(); const table = createSvelteTable({ get data() { return data; }, get columns() { return columns; }, - getCoreRowModel: getCoreRowModel(), - manualPagination: true, - get pageCount() { return pageCount; }, + getCoreRowModel: getCoreRowModel() }); - function handlePageChange(newPage: number) { - const url = new URL($page.url); - url.searchParams.set('page', newPage.toString()); - goto(url, { keepFocus: true, noScroll: true }); - } + let scrollContainer = $state(); + let loadingTrigger = $state(); - const currentPage = $derived(Number($page.url.searchParams.get('page') || 1)); + onMount(() => { + const observer = new IntersectionObserver( + (entries) => { + const [entry] = entries; + if (entry.isIntersecting && hasMore && !loading) { + loadMore(); + } + }, + { root: scrollContainer, threshold: 0.1 } + ); + + if (loadingTrigger) observer.observe(loadingTrigger); + + return () => observer.disconnect(); + }); -
- - - {#each table.getHeaderGroups() as headerGroup (headerGroup.id)} - - {#each headerGroup.headers as header (header.id)} - - {#if !header.isPlaceholder} +
+
+ + + {#each table.getHeaderGroups() as headerGroup (headerGroup.id)} + + {#each headerGroup.headers as header (header.id)} + + {/each} + + {/each} + + + {#each table.getRowModel().rows as row (row.id)} + + {#each row.getVisibleCells() as cell (cell.id)} + + {/each} + + {:else} + + + + {/each} + + + {#if hasMore} + + + + {/if} + +
+ {#if !header.isPlaceholder} + + {/if} +
- {/if} - - {/each} - - {/each} - - - {#each table.getRowModel().rows as row (row.id)} - - {#each row.getVisibleCells() as cell (cell.id)} - - - - {/each} - - {:else} - - - No hay resultados. - - - {/each} - - - - -
-
- Total: {totalItems} registros -
-
- - +
+ No hay resultados. +
+
+ {#if loading} +
+
+ Cargando más registros... +
+ {:else} +
+ + Desplázate para cargar más + +
+ {/if} +
+
diff --git a/frontend/src/lib/components/dashboard/reference_data/invoice_types/data-table-actions.svelte b/frontend/src/lib/components/dashboard/reference_data/invoice_types/data-table-actions.svelte index be22d1e5..4fab7cbe 100644 --- a/frontend/src/lib/components/dashboard/reference_data/invoice_types/data-table-actions.svelte +++ b/frontend/src/lib/components/dashboard/reference_data/invoice_types/data-table-actions.svelte @@ -3,9 +3,7 @@ import { Button } from "$lib/components/ui/button/index.js"; import * as DropdownMenu from "$lib/components/ui/dropdown-menu/index.js"; import type { InvoiceType } from "./columns.js"; - import CreateEditDialog from "./create-edit-dialog.svelte"; import DetailsDialog from "./details-dialog.svelte"; - import DeleteDialog from "./delete-dialog.svelte"; let { item, @@ -16,8 +14,6 @@ } = $props(); let showDetailsDialog = $state(false); - let showEditDialog = $state(false); - let showDeleteDialog = $state(false); function handleCopyId() { navigator.clipboard.writeText(item.key.toString()); @@ -26,14 +22,6 @@ function handleViewDetails() { showDetailsDialog = true; } - - function handleEdit() { - showEditDialog = true; - } - - function handleDelete() { - showDeleteDialog = true; - } @@ -54,13 +42,8 @@ Ver detalles - Editar - - Eliminar - - 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 2f4a88e7..4109783b 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 @@ -59,68 +59,67 @@ }); -
-
- - +
+
+ + {#each table.getHeaderGroups() as headerGroup (headerGroup.id)} - + {#each headerGroup.headers as header (header.id)} - + {/each} - + {/each} - - + + {#each table.getRowModel().rows as row (row.id)} - + {#each row.getVisibleCells() as cell (cell.id)} - + {/each} - + {:else} - - + + + {/each} - + {#if hasMore} - - -
+
+ + {/if} - - + +
{#if !header.isPlaceholder} {/if} - +
- +
No hay resultados. - - +
+
{#if loading} -
-
- Cargando más... +
+
+ Cargando más registros...
{:else} -
- Desplázate para cargar más +
+ + Desplázate para cargar más +
{/if}
- - +
diff --git a/frontend/src/lib/components/dashboard/reference_data/material_types/data-table-actions.svelte b/frontend/src/lib/components/dashboard/reference_data/material_types/data-table-actions.svelte index 8b64e467..d1f070f7 100644 --- a/frontend/src/lib/components/dashboard/reference_data/material_types/data-table-actions.svelte +++ b/frontend/src/lib/components/dashboard/reference_data/material_types/data-table-actions.svelte @@ -3,9 +3,7 @@ import { Button } from "$lib/components/ui/button/index.js"; import * as DropdownMenu from "$lib/components/ui/dropdown-menu/index.js"; import type { MaterialType } from "./columns.js"; - import CreateEditDialog from "./create-edit-dialog.svelte"; import DetailsDialog from "./details-dialog.svelte"; - import DeleteDialog from "./delete-dialog.svelte"; let { item, @@ -16,8 +14,6 @@ } = $props(); let showDetailsDialog = $state(false); - let showEditDialog = $state(false); - let showDeleteDialog = $state(false); function handleCopyId() { navigator.clipboard.writeText(item.key.toString()); @@ -26,14 +22,6 @@ function handleViewDetails() { showDetailsDialog = true; } - - function handleEdit() { - showEditDialog = true; - } - - function handleDelete() { - showDeleteDialog = true; - } @@ -54,13 +42,8 @@ Ver detalles - Editar - - Eliminar - - 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 2f4a88e7..4109783b 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 @@ -59,68 +59,67 @@ }); -
-
- - +
+
+ + {#each table.getHeaderGroups() as headerGroup (headerGroup.id)} - + {#each headerGroup.headers as header (header.id)} - + {/each} - + {/each} - - + + {#each table.getRowModel().rows as row (row.id)} - + {#each row.getVisibleCells() as cell (cell.id)} - + {/each} - + {:else} - - + + + {/each} - + {#if hasMore} - - -
+
+ + {/if} - - + +
{#if !header.isPlaceholder} {/if} - +
- +
No hay resultados. - - +
+
{#if loading} -
-
- Cargando más... +
+
+ Cargando más registros...
{:else} -
- Desplázate para cargar más +
+ + Desplázate para cargar más +
{/if}
- - +
diff --git a/frontend/src/lib/components/dashboard/reference_data/payment_methods/data-table-actions.svelte b/frontend/src/lib/components/dashboard/reference_data/payment_methods/data-table-actions.svelte index faea7dde..f36a0c6a 100644 --- a/frontend/src/lib/components/dashboard/reference_data/payment_methods/data-table-actions.svelte +++ b/frontend/src/lib/components/dashboard/reference_data/payment_methods/data-table-actions.svelte @@ -3,9 +3,7 @@ import { Button } from "$lib/components/ui/button/index.js"; import * as DropdownMenu from "$lib/components/ui/dropdown-menu/index.js"; import type { PaymentMethod } from "./columns.js"; - import CreateEditDialog from "./create-edit-dialog.svelte"; import DetailsDialog from "./details-dialog.svelte"; - import DeleteDialog from "./delete-dialog.svelte"; let { item, @@ -16,8 +14,6 @@ } = $props(); let showDetailsDialog = $state(false); - let showEditDialog = $state(false); - let showDeleteDialog = $state(false); function handleCopyId() { navigator.clipboard.writeText(item.key.toString()); @@ -26,14 +22,6 @@ function handleViewDetails() { showDetailsDialog = true; } - - function handleEdit() { - showEditDialog = true; - } - - function handleDelete() { - showDeleteDialog = true; - } @@ -54,13 +42,8 @@ Ver detalles - Editar - - Eliminar - - 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 2f4a88e7..4109783b 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 @@ -59,68 +59,67 @@ }); -
-
- - +
+
+ + {#each table.getHeaderGroups() as headerGroup (headerGroup.id)} - + {#each headerGroup.headers as header (header.id)} - + {/each} - + {/each} - - + + {#each table.getRowModel().rows as row (row.id)} - + {#each row.getVisibleCells() as cell (cell.id)} - + {/each} - + {:else} - - + + + {/each} - + {#if hasMore} - - -
+
+ + {/if} - - + +
{#if !header.isPlaceholder} {/if} - +
- +
No hay resultados. - - +
+
{#if loading} -
-
- Cargando más... +
+
+ Cargando más registros...
{:else} -
- Desplázate para cargar más +
+ + Desplázate para cargar más +
{/if}
- - +
diff --git a/frontend/src/lib/components/dashboard/reference_data/pedimento_codes/data-table-actions.svelte b/frontend/src/lib/components/dashboard/reference_data/pedimento_codes/data-table-actions.svelte index 21b69276..5bfd8144 100644 --- a/frontend/src/lib/components/dashboard/reference_data/pedimento_codes/data-table-actions.svelte +++ b/frontend/src/lib/components/dashboard/reference_data/pedimento_codes/data-table-actions.svelte @@ -3,9 +3,7 @@ import { Button } from "$lib/components/ui/button/index.js"; import * as DropdownMenu from "$lib/components/ui/dropdown-menu/index.js"; import type { PedimentoCode } from "./columns.js"; - import CreateEditDialog from "./create-edit-dialog.svelte"; import DetailsDialog from "./details-dialog.svelte"; - import DeleteDialog from "./delete-dialog.svelte"; let { item, @@ -16,8 +14,6 @@ } = $props(); let showDetailsDialog = $state(false); - let showEditDialog = $state(false); - let showDeleteDialog = $state(false); function handleCopyId() { navigator.clipboard.writeText(item.code.toString()); @@ -26,14 +22,6 @@ function handleViewDetails() { showDetailsDialog = true; } - - function handleEdit() { - showEditDialog = true; - } - - function handleDelete() { - showDeleteDialog = true; - } @@ -54,13 +42,8 @@ Ver detalles - Editar - - Eliminar - - 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 2f4a88e7..4109783b 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 @@ -59,68 +59,67 @@ }); -
-
- - +
+
+ + {#each table.getHeaderGroups() as headerGroup (headerGroup.id)} - + {#each headerGroup.headers as header (header.id)} - + {/each} - + {/each} - - + + {#each table.getRowModel().rows as row (row.id)} - + {#each row.getVisibleCells() as cell (cell.id)} - + {/each} - + {:else} - - + + + {/each} - + {#if hasMore} - - -
+
+ + {/if} - - + +
{#if !header.isPlaceholder} {/if} - +
- +
No hay resultados. - - +
+
{#if loading} -
-
- Cargando más... +
+
+ Cargando más registros...
{:else} -
- Desplázate para cargar más +
+ + Desplázate para cargar más +
{/if}
- - +
diff --git a/frontend/src/lib/components/dashboard/reference_data/pedimento_regimens/data-table-actions.svelte b/frontend/src/lib/components/dashboard/reference_data/pedimento_regimens/data-table-actions.svelte index 42b87981..dc4d01ad 100644 --- a/frontend/src/lib/components/dashboard/reference_data/pedimento_regimens/data-table-actions.svelte +++ b/frontend/src/lib/components/dashboard/reference_data/pedimento_regimens/data-table-actions.svelte @@ -3,9 +3,7 @@ import { Button } from "$lib/components/ui/button/index.js"; import * as DropdownMenu from "$lib/components/ui/dropdown-menu/index.js"; import type { PedimentoRegimen } from "./columns.js"; - import CreateEditDialog from "./create-edit-dialog.svelte"; import DetailsDialog from "./details-dialog.svelte"; - import DeleteDialog from "./delete-dialog.svelte"; let { item, @@ -16,8 +14,6 @@ } = $props(); let showDetailsDialog = $state(false); - let showEditDialog = $state(false); - let showDeleteDialog = $state(false); function handleCopyId() { navigator.clipboard.writeText(item.code.toString()); @@ -26,14 +22,6 @@ function handleViewDetails() { showDetailsDialog = true; } - - function handleEdit() { - showEditDialog = true; - } - - function handleDelete() { - showDeleteDialog = true; - } @@ -54,13 +42,8 @@ Ver detalles - Editar - - Eliminar - - 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 2f4a88e7..4109783b 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 @@ -59,68 +59,67 @@ }); -
-
- - +
+
+ + {#each table.getHeaderGroups() as headerGroup (headerGroup.id)} - + {#each headerGroup.headers as header (header.id)} - + {/each} - + {/each} - - + + {#each table.getRowModel().rows as row (row.id)} - + {#each row.getVisibleCells() as cell (cell.id)} - + {/each} - + {:else} - - + + + {/each} - + {#if hasMore} - - -
+
+ + {/if} - - + +
{#if !header.isPlaceholder} {/if} - +
- +
No hay resultados. - - +
+
{#if loading} -
-
- Cargando más... +
+
+ Cargando más registros...
{:else} -
- Desplázate para cargar más +
+ + Desplázate para cargar más +
{/if}
- - +
diff --git a/frontend/src/lib/components/dashboard/reference_data/sectors/create-edit-dialog.svelte b/frontend/src/lib/components/dashboard/reference_data/sectors/create-edit-dialog.svelte index 1da14dbf..460e1202 100644 --- a/frontend/src/lib/components/dashboard/reference_data/sectors/create-edit-dialog.svelte +++ b/frontend/src/lib/components/dashboard/reference_data/sectors/create-edit-dialog.svelte @@ -25,6 +25,19 @@ let loading = $state(false); let error = $state(null); + function getActiveCompanyId(): number | null { + const fromStore = companyStore.activeCompany?.id; + if (fromStore) return fromStore; + if (typeof document === 'undefined') return null; + const cookie = document.cookie + .split('; ') + .find((row) => row.startsWith('active_company_id=')) + ?.split('=')[1]; + if (!cookie) return null; + const parsed = Number(cookie); + return Number.isFinite(parsed) ? parsed : null; + } + // Actualizar formData cuando item cambia $effect(() => { if (item) { @@ -49,7 +62,7 @@ loading = true; error = null; - const companyId = companyStore.activeCompany?.id; + const companyId = getActiveCompanyId(); if (!companyId) { error = 'No hay empresa activa seleccionada'; loading = false; 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 2f4a88e7..4109783b 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 @@ -59,68 +59,67 @@ }); -
-
- - +
+
+ + {#each table.getHeaderGroups() as headerGroup (headerGroup.id)} - + {#each headerGroup.headers as header (header.id)} - + {/each} - + {/each} - - + + {#each table.getRowModel().rows as row (row.id)} - + {#each row.getVisibleCells() as cell (cell.id)} - + {/each} - + {:else} - - + + + {/each} - + {#if hasMore} - - -
+
+ + {/if} - - + +
{#if !header.isPlaceholder} {/if} - +
- +
No hay resultados. - - +
+
{#if loading} -
-
- Cargando más... +
+
+ Cargando más registros...
{:else} -
- Desplázate para cargar más +
+ + Desplázate para cargar más +
{/if}
- - +
diff --git a/frontend/src/lib/components/dashboard/reference_data/sectors/delete-dialog.svelte b/frontend/src/lib/components/dashboard/reference_data/sectors/delete-dialog.svelte index 9e92fb82..920913e9 100644 --- a/frontend/src/lib/components/dashboard/reference_data/sectors/delete-dialog.svelte +++ b/frontend/src/lib/components/dashboard/reference_data/sectors/delete-dialog.svelte @@ -18,10 +18,23 @@ let loading = $state(false); let error = $state(null); + function getActiveCompanyId(): number | null { + const fromStore = companyStore.activeCompany?.id; + if (fromStore) return fromStore; + if (typeof document === 'undefined') return null; + const cookie = document.cookie + .split('; ') + .find((row) => row.startsWith('active_company_id=')) + ?.split('=')[1]; + if (!cookie) return null; + const parsed = Number(cookie); + return Number.isFinite(parsed) ? parsed : null; + } + async function handleDelete() { if (!item) return; - const companyId = companyStore.activeCompany?.id; + const companyId = getActiveCompanyId(); if (!companyId) { error = 'No hay empresa activa seleccionada'; return; 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 2f4a88e7..4109783b 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 @@ -59,68 +59,67 @@ }); -
-
- - +
+
+ + {#each table.getHeaderGroups() as headerGroup (headerGroup.id)} - + {#each headerGroup.headers as header (header.id)} - + {/each} - + {/each} - - + + {#each table.getRowModel().rows as row (row.id)} - + {#each row.getVisibleCells() as cell (cell.id)} - + {/each} - + {:else} - - + + + {/each} - + {#if hasMore} - - -
+
+ + {/if} - - + +
{#if !header.isPlaceholder} {/if} - +
- +
No hay resultados. - - +
+
{#if loading} -
-
- Cargando más... +
+
+ Cargando más registros...
{:else} -
- Desplázate para cargar más +
+ + Desplázate para cargar más +
{/if}
- - +
diff --git a/frontend/src/lib/components/dashboard/reference_data/transport_modes/data-table-actions.svelte b/frontend/src/lib/components/dashboard/reference_data/transport_modes/data-table-actions.svelte index 9159af82..5855ea10 100644 --- a/frontend/src/lib/components/dashboard/reference_data/transport_modes/data-table-actions.svelte +++ b/frontend/src/lib/components/dashboard/reference_data/transport_modes/data-table-actions.svelte @@ -3,9 +3,7 @@ import { Button } from "$lib/components/ui/button/index.js"; import * as DropdownMenu from "$lib/components/ui/dropdown-menu/index.js"; import type { TransportMode } from "./columns.js"; - import CreateEditDialog from "./create-edit-dialog.svelte"; import DetailsDialog from "./details-dialog.svelte"; - import DeleteDialog from "./delete-dialog.svelte"; let { item, @@ -16,8 +14,6 @@ } = $props(); let showDetailsDialog = $state(false); - let showEditDialog = $state(false); - let showDeleteDialog = $state(false); function handleCopyId() { navigator.clipboard.writeText(item.key.toString()); @@ -26,14 +22,6 @@ function handleViewDetails() { showDetailsDialog = true; } - - function handleEdit() { - showEditDialog = true; - } - - function handleDelete() { - showDeleteDialog = true; - } @@ -54,13 +42,8 @@ Ver detalles - Editar - - Eliminar - - 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 2f4a88e7..4109783b 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 @@ -59,68 +59,67 @@ }); -
-
- - +
+
+ + {#each table.getHeaderGroups() as headerGroup (headerGroup.id)} - + {#each headerGroup.headers as header (header.id)} - + {/each} - + {/each} - - + + {#each table.getRowModel().rows as row (row.id)} - + {#each row.getVisibleCells() as cell (cell.id)} - + {/each} - + {:else} - - + + + {/each} - + {#if hasMore} - - -
+
+ + {/if} - - + +
{#if !header.isPlaceholder} {/if} - +
- +
No hay resultados. - - +
+
{#if loading} -
-
- Cargando más... +
+
+ Cargando más registros...
{:else} -
- Desplázate para cargar más +
+ + Desplázate para cargar más +
{/if}
- - +
diff --git a/frontend/src/lib/components/dashboard/reference_data/transport_types/data-table-actions.svelte b/frontend/src/lib/components/dashboard/reference_data/transport_types/data-table-actions.svelte index 6c4f2e5b..de253afb 100644 --- a/frontend/src/lib/components/dashboard/reference_data/transport_types/data-table-actions.svelte +++ b/frontend/src/lib/components/dashboard/reference_data/transport_types/data-table-actions.svelte @@ -3,9 +3,7 @@ import { Button } from "$lib/components/ui/button/index.js"; import * as DropdownMenu from "$lib/components/ui/dropdown-menu/index.js"; import type { TransportType } from "./columns.js"; - import CreateEditDialog from "./create-edit-dialog.svelte"; import DetailsDialog from "./details-dialog.svelte"; - import DeleteDialog from "./delete-dialog.svelte"; let { item, @@ -16,8 +14,6 @@ } = $props(); let showDetailsDialog = $state(false); - let showEditDialog = $state(false); - let showDeleteDialog = $state(false); function handleCopyId() { navigator.clipboard.writeText(item.transport_code.toString()); @@ -26,14 +22,6 @@ function handleViewDetails() { showDetailsDialog = true; } - - function handleEdit() { - showEditDialog = true; - } - - function handleDelete() { - showDeleteDialog = true; - } @@ -54,13 +42,8 @@ Ver detalles - Editar - - Eliminar - - 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 2f4a88e7..4109783b 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 @@ -59,68 +59,67 @@ }); -
-
- - +
+
+ + {#each table.getHeaderGroups() as headerGroup (headerGroup.id)} - + {#each headerGroup.headers as header (header.id)} - + {/each} - + {/each} - - + + {#each table.getRowModel().rows as row (row.id)} - + {#each row.getVisibleCells() as cell (cell.id)} - + {/each} - + {:else} - - + + + {/each} - + {#if hasMore} - - -
+
+ + {/if} - - + +
{#if !header.isPlaceholder} {/if} - +
- +
No hay resultados. - - +
+
{#if loading} -
-
- Cargando más... +
+
+ Cargando más registros...
{:else} -
- Desplázate para cargar más +
+ + Desplázate para cargar más +
{/if}
- - +
diff --git a/frontend/src/lib/components/dashboard/reference_data/valuation_methods/data-table-actions.svelte b/frontend/src/lib/components/dashboard/reference_data/valuation_methods/data-table-actions.svelte index cf14da9a..f4bf003f 100644 --- a/frontend/src/lib/components/dashboard/reference_data/valuation_methods/data-table-actions.svelte +++ b/frontend/src/lib/components/dashboard/reference_data/valuation_methods/data-table-actions.svelte @@ -3,9 +3,7 @@ import { Button } from "$lib/components/ui/button/index.js"; import * as DropdownMenu from "$lib/components/ui/dropdown-menu/index.js"; import type { ValuationMethod } from "./columns.js"; - import CreateEditDialog from "./create-edit-dialog.svelte"; import DetailsDialog from "./details-dialog.svelte"; - import DeleteDialog from "./delete-dialog.svelte"; let { item, @@ -16,8 +14,6 @@ } = $props(); let showDetailsDialog = $state(false); - let showEditDialog = $state(false); - let showDeleteDialog = $state(false); function handleCopyId() { navigator.clipboard.writeText(item.key.toString()); @@ -26,14 +22,6 @@ function handleViewDetails() { showDetailsDialog = true; } - - function handleEdit() { - showEditDialog = true; - } - - function handleDelete() { - showDeleteDialog = true; - } @@ -54,13 +42,8 @@ Ver detalles - Editar - - Eliminar - - 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 36558b68..5b63e0a2 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 @@ -60,68 +60,67 @@ -
-
- - +
+
+ + {#each table.getHeaderGroups() as headerGroup (headerGroup.id)} - + {#each headerGroup.headers as header (header.id)} - + {/each} - + {/each} - - + + {#each table.getRowModel().rows as row (row.id)} - + {#each row.getVisibleCells() as cell (cell.id)} - + {/each} - + {:else} - - + + + {/each} - + {#if hasMore} - - -
+
+ + {/if} - - + +
{#if !header.isPlaceholder} {/if} - +
- +
No hay resultados. - - +
+
{#if loading} -
-
- Cargando más... +
+
+ Cargando más registros...
{:else} -
- Desplázate para cargar más +
+ + Desplázate para cargar más +
{/if}
- - +
diff --git a/frontend/src/lib/components/ui/sidebar/sidebar-inset.svelte b/frontend/src/lib/components/ui/sidebar/sidebar-inset.svelte index d862761d..5d9598f5 100644 --- a/frontend/src/lib/components/ui/sidebar/sidebar-inset.svelte +++ b/frontend/src/lib/components/ui/sidebar/sidebar-inset.svelte @@ -14,7 +14,7 @@ bind:this={ref} data-slot="sidebar-inset" class={cn( - "bg-background relative flex w-full flex-1 flex-col", + "bg-background relative flex min-h-0 w-full flex-1 flex-col overflow-hidden", "md:peer-data-[variant=inset]:m-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:peer-data-[state=collapsed]:ml-2 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow-sm", className )} diff --git a/frontend/src/lib/components/ui/sidebar/sidebar-provider.svelte b/frontend/src/lib/components/ui/sidebar/sidebar-provider.svelte index 5b0d0aa2..f9f8f9dc 100644 --- a/frontend/src/lib/components/ui/sidebar/sidebar-provider.svelte +++ b/frontend/src/lib/components/ui/sidebar/sidebar-provider.svelte @@ -42,7 +42,7 @@ data-slot="sidebar-wrapper" style="--sidebar-width: {SIDEBAR_WIDTH}; --sidebar-width-icon: {SIDEBAR_WIDTH_ICON}; {style}" class={cn( - "group/sidebar-wrapper has-data-[variant=inset]:bg-sidebar flex min-h-svh w-full", + "group/sidebar-wrapper has-data-[variant=inset]:bg-sidebar flex h-svh w-full overflow-hidden", className )} bind:this={ref} diff --git a/frontend/src/lib/config/shortcuts/dashboard/reference_data/common/factory.ts b/frontend/src/lib/config/shortcuts/dashboard/reference_data/common/factory.ts index 562c133e..6a487710 100644 --- a/frontend/src/lib/config/shortcuts/dashboard/reference_data/common/factory.ts +++ b/frontend/src/lib/config/shortcuts/dashboard/reference_data/common/factory.ts @@ -4,19 +4,24 @@ import type { ShortcutDef } from '$lib/stores/shortcut-store'; * Reusable shortcuts for simple reference data catalogs. */ export const obtenerAtajosReferenceDataSimple = (acciones: { - manejarNuevo: () => void; + manejarNuevo?: () => void; manejarActualizar: () => void; }): ShortcutDef[] => { - return [ - { + const atajos: ShortcutDef[] = []; + + if (acciones.manejarNuevo) { + atajos.push({ key: 'Alt+Shift+N', description: 'Nuevo Registro', action: acciones.manejarNuevo - }, - { - key: 'Alt+Shift+R', - description: 'Actualizar Lista', - action: acciones.manejarActualizar - } - ]; + }); + } + + atajos.push({ + key: 'Alt+Shift+R', + description: 'Actualizar Lista', + action: acciones.manejarActualizar + }); + + return atajos; }; diff --git a/frontend/src/routes/dashboard/+layout.svelte b/frontend/src/routes/dashboard/+layout.svelte index 12e28e3f..b9cca54b 100644 --- a/frontend/src/routes/dashboard/+layout.svelte +++ b/frontend/src/routes/dashboard/+layout.svelte @@ -141,7 +141,7 @@ -->
-
+
{#if csvImportBanner} -
+

{m['sidebar.audit_logs_title']()}

diff --git a/frontend/src/routes/dashboard/audit_logs/bitacora-tab.svelte b/frontend/src/routes/dashboard/audit_logs/bitacora-tab.svelte index da1e2bd7..0269e9e3 100644 --- a/frontend/src/routes/dashboard/audit_logs/bitacora-tab.svelte +++ b/frontend/src/routes/dashboard/audit_logs/bitacora-tab.svelte @@ -8,7 +8,6 @@ import * as Card from '$lib/components/ui/card'; import { Button } from '$lib/components/ui/button'; import { Input } from '$lib/components/ui/input'; - import { Label } from '$lib/components/ui/label'; import * as Table from '$lib/components/ui/table'; import { RefreshCw, Search } from 'lucide-svelte'; @@ -153,106 +152,78 @@
-
- -
- -
- - - Filtros - - -
-
- -
- - -
-
- -
- - -
- -
- - -
- -
- - -
- -
- - -
-
-
- -
-
-
-
-
- Registros - Total: {total} registros encontrados + Bitácora de Auditoría + Mostrando {logs.length} de {total} registros +
+
+
+ + +
+ + + + - + + +
diff --git a/frontend/src/routes/dashboard/audit_logs/files-tab.svelte b/frontend/src/routes/dashboard/audit_logs/files-tab.svelte index 051df209..fc652973 100644 --- a/frontend/src/routes/dashboard/audit_logs/files-tab.svelte +++ b/frontend/src/routes/dashboard/audit_logs/files-tab.svelte @@ -80,58 +80,53 @@
-
-
-

{m['sidebar.audit_logs_files_title']()}

-

{displayPath || m['sidebar.audit_logs_files_root']()}

-
- -
- - - -
- {#each breadcrumbs as crumb, idx} - {#if idx > 0} - / - {/if} - {#if idx === breadcrumbs.length - 1} - - {crumb.display_name} - - {:else} - - {/if} - {/each} -
-
-
- - - {m['sidebar.audit_logs_files_list_title']()} + +
+
+ {m['sidebar.audit_logs_files_title']()} + +
+ {#each breadcrumbs as crumb, idx} + {#if idx > 0} + / + {/if} + {#if idx === breadcrumbs.length - 1} + + {crumb.display_name} + + {:else} + + {/if} + {/each} + {#if breadcrumbs.length === 0} + {m['sidebar.audit_logs_files_root']()} + {/if} +
+
+
+ +
- + {#if error} -
+
{m['sidebar.audit_logs_files_error_prefix']()} {error}
{/if} -
+
- + {m['sidebar.audit_logs_files_col_name']()} @@ -163,7 +158,7 @@ {:else} {#each folders as folder} void loadPath(folder.path)} > @@ -178,7 +173,7 @@ {/each} {#each files as file} - + {file.display_name} diff --git a/frontend/src/routes/dashboard/audit_logs/tasks-tab.svelte b/frontend/src/routes/dashboard/audit_logs/tasks-tab.svelte index 957e4c1e..e81ba92b 100644 --- a/frontend/src/routes/dashboard/audit_logs/tasks-tab.svelte +++ b/frontend/src/routes/dashboard/audit_logs/tasks-tab.svelte @@ -6,9 +6,9 @@ type UnifiedTaskStatus } from '$lib/api/dashboard/a76/tasks'; import { companyStore } from '$lib/stores/company.svelte'; + import * as Card from '$lib/components/ui/card'; import { Button } from '$lib/components/ui/button'; import { Input } from '$lib/components/ui/input'; - import * as Select from '$lib/components/ui/select'; import * as Dialog from '$lib/components/ui/dialog'; import { Badge } from '$lib/components/ui/badge'; @@ -146,106 +146,116 @@ }); -
-
- -
+
+ + +
+
+ Tareas del Sistema + Total: {total} tareas encontradas +
+
+ + + + +
+
+
+ + {#if error} +
+ {error} +
+ {/if} -
- - - - - Todos - En cola - En progreso - Completadas - Fallidas - - - -
- - {#if error} -
- {error} -
- {/if} - -
- - - - - - - - - - - - - {#if tasks.length === 0 && !loading} - - - - {:else if tasks.length === 0 && loading} - - - - {:else} - {#each tasks as task} - void openDetail(task)} - > - - - - - - +
+
Task IDTipoEstadoProgresoReintentosActualizado
Sin tareas registradas
Cargando...
{task.task_id}{task.task_group} / {task.task_name} - {statusLabel(task.status)} - ({task.celery_state_raw}) - - {formatPercent(task)} - {task.progress?.message ? ` · ${task.progress.message}` : ''} - {task.retries ?? 0}{new Date(task.updated_at).toLocaleString()}
+ + + + + + + + - {/each} - {/if} - -
Task IDTipoEstadoProgresoReintentosActualizado
-
- -
-
Total: {total}
-
- - Página {page} - + + + {#if tasks.length === 0 && !loading} + + Sin tareas registradas + + {:else if tasks.length === 0 && loading} + + Cargando... + + {:else} + {#each tasks as task} + void openDetail(task)} + > + {task.task_id} + {task.task_group} / {task.task_name} + + {statusLabel(task.status)} + ({task.celery_state_raw}) + + + {formatPercent(task)} + {task.progress?.message ? ` · ${task.progress.message}` : ''} + + {task.retries ?? 0} + {new Date(task.updated_at).toLocaleString()} + + {/each} + {/if} + + +
+ +
+
Total: {total}
+
+ + Página {page} + +
-
+
(showCreateDialog = true), manejarActualizar: reloadData }) ); - // Sincronizar token de cookies a localStorage al montar el componente + // Sincronizar token de cookies onMount(() => { if (browser) { - // Función para obtener el valor de una cookie const getCookie = (name: string): string | null => { const value = `; ${document.cookie}`; const parts = value.split(`; ${name}=`); if (parts.length === 2) return parts.pop()?.split(';').shift() || null; return null; }; - - // Verificar si hay token en las cookies const cookieToken = getCookie('access_token'); const localToken = localStorage.getItem('access_token'); - - if (cookieToken && cookieToken !== localToken) { - localStorage.setItem('access_token', cookieToken); - } - - // También sincronizar refresh_token si existe - const cookieRefreshToken = getCookie('refresh_token'); - const localRefreshToken = localStorage.getItem('refresh_token'); - - if (cookieRefreshToken && cookieRefreshToken !== localRefreshToken) { - localStorage.setItem('refresh_token', cookieRefreshToken); - } + if (cookieToken && cookieToken !== localToken) localStorage.setItem('access_token', cookieToken); } }); @@ -65,116 +47,118 @@ let hasMore = $derived(allItems.length < totalItems); let error = $state(data.error || null); + // Filtros + let searchQuery = $state($page.url.searchParams.get('search') || ''); + let timeout: ReturnType; + + function handleSearch() { + if (!browser) return; + clearTimeout(timeout); + timeout = setTimeout(async () => { + loading = true; + try { + const response = await codePedimentoRegimensApi.list(1, pageSize, searchQuery); + if (!response.error && response.data) { + allItems = response.data.items; + currentPage = 1; + totalItems = response.data.total; + } + } catch (e) { + console.error('Error aplicando filtros:', e); + } finally { + loading = false; + } + const url = new URL($page.url); + if (searchQuery) url.searchParams.set('search', searchQuery); + else url.searchParams.delete('search'); + history.replaceState(history.state, '', url); + }, 500); + } + async function loadMore() { if (loading || !hasMore) return; - loading = true; error = null; - - try { - const response = await codePedimentoRegimensApi.list(currentPage + 1, pageSize); - + try { + const response = await codePedimentoRegimensApi.list(currentPage + 1, pageSize, searchQuery); if (response.error) { - console.error('📊 [Page] Error en loadMore:', response.error, 'Status:', response.status); - - // Si es un error de autenticación (401 o 403) y no se pudo refrescar, mostrar mensaje específico if (response.status === 401 || response.status === 403) { error = 'Sesión expirada. Recargando página...'; - // Recargar automáticamente después de 2 segundos - setTimeout(() => { - window.location.reload(); - }, 2000); + setTimeout(() => window.location.reload(), 2000); } else { error = response.error; } return; } - - if (response.data?.items) { - // Agregar los nuevos items al array existente + if (response.data?.items) { allItems = [...allItems, ...response.data.items]; currentPage++; totalItems = response.data.total; } } catch (e) { error = 'Error cargando más datos'; - console.error('📊 [Page] Error loading more:', e); } finally { loading = false; } } function reloadData() { - // Reset y recargar desde el principio window.location.reload(); } - function handleCreateClick() { - showCreateDialog = true; - } - function handleSuccess() { - // Recargar datos después de crear/editar/eliminar reloadData(); } - // Crear columnas con el callback onSuccess const columns = createColumns(handleSuccess); -
- -
-
-

Código Pedimento - Regímenes

+
+ +
+
+

+ Pedimento - Regímenes +

- Gestiona las relaciones entre códigos de pedimento y regímenes + Relación entre códigos de pedimento y regímenes aduaneros

- +
+ +
+
+ + +
+
+ Búsqueda General + +
- {#if error} - - - Error - {error} - - +
+ {error} +
{/if} - - - -
-
- Listado de Relaciones - - 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 fdb94c31..035da5d0 100644 --- a/frontend/src/routes/dashboard/reference_data/containers/+page.svelte +++ b/frontend/src/routes/dashboard/reference_data/containers/+page.svelte @@ -3,56 +3,29 @@ 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 CreateEditDialog from '$lib/components/dashboard/reference_data/containers/create-edit-dialog.svelte'; - import * as Card from '$lib/components/ui/card'; import { Button } from '$lib/components/ui/button'; - import type { PageData } from './$types'; - import { useShortcuts } from '$lib/hooks/use-shortcuts'; - import { obtenerAtajosLista } from '$lib/config/shortcuts/dashboard/reference_data/containers/list'; + import { Input } from '$lib/components/ui/input'; + import { page } from '$app/stores'; import { browser } from '$app/environment'; - import { Plus, RefreshCw } from 'lucide-svelte'; + import { RefreshCw } from 'lucide-svelte'; + import { useShortcuts } from '$lib/hooks/use-shortcuts'; + import type { PageData } from './$types'; // Los datos iniciales vienen del servidor let { data }: { data: PageData } = $props(); - - // Estado para el diálogo de crear - let showCreateDialog = $state(false); - // Atajos - useShortcuts( - 'Lista Contenedores', - obtenerAtajosLista({ - manejarNuevo: () => (showCreateDialog = true), - manejarActualizar: reloadData - }) - ); - - // Sincronizar token de cookies a localStorage al montar el componente + // Sincronizar token de cookies onMount(() => { if (browser) { - // Función para obtener el valor de una cookie const getCookie = (name: string): string | null => { const value = `; ${document.cookie}`; const parts = value.split(`; ${name}=`); if (parts.length === 2) return parts.pop()?.split(';').shift() || null; return null; }; - - // Verificar si hay token en las cookies const cookieToken = getCookie('access_token'); const localToken = localStorage.getItem('access_token'); - - if (cookieToken && cookieToken !== localToken) { - localStorage.setItem('access_token', cookieToken); - } - - // También sincronizar refresh_token si existe - const cookieRefreshToken = getCookie('refresh_token'); - const localRefreshToken = localStorage.getItem('refresh_token'); - - if (cookieRefreshToken && cookieRefreshToken !== localRefreshToken) { - localStorage.setItem('refresh_token', cookieRefreshToken); - } + if (cookieToken && cookieToken !== localToken) localStorage.setItem('access_token', cookieToken); } }); @@ -65,116 +38,116 @@ let hasMore = $derived(allItems.length < totalItems); let error = $state(data.error || null); + // Filtros + let searchQuery = $state($page.url.searchParams.get('search') || ''); + let timeout: ReturnType; + + function handleSearch() { + if (!browser) return; + clearTimeout(timeout); + timeout = setTimeout(async () => { + loading = true; + try { + const response = await containersApi.list(1, pageSize, searchQuery); + if (!response.error && response.data) { + allItems = response.data.items; + currentPage = 1; + totalItems = response.data.total; + } + } catch (e) { + console.error('Error aplicando filtros:', e); + } finally { + loading = false; + } + const url = new URL($page.url); + if (searchQuery) url.searchParams.set('search', searchQuery); + else url.searchParams.delete('search'); + history.replaceState(history.state, '', url); + }, 500); + } + async function loadMore() { if (loading || !hasMore) return; - loading = true; error = null; - - try { - const response = await containersApi.list(currentPage + 1, pageSize); - + try { + const response = await containersApi.list(currentPage + 1, pageSize, searchQuery); if (response.error) { - console.error('📊 [Page] Error en loadMore:', response.error, 'Status:', response.status); - - // Si es un error de autenticación (401 o 403) y no se pudo refrescar, mostrar mensaje específico if (response.status === 401 || response.status === 403) { error = 'Sesión expirada. Recargando página...'; - // Recargar automáticamente después de 2 segundos - setTimeout(() => { - window.location.reload(); - }, 2000); + setTimeout(() => window.location.reload(), 2000); } else { error = response.error; } return; } - - if (response.data?.items) { - // Agregar los nuevos items al array existente + if (response.data?.items) { allItems = [...allItems, ...response.data.items]; currentPage++; totalItems = response.data.total; } } catch (e) { error = 'Error cargando más datos'; - console.error('📊 [Page] Error loading more:', e); } finally { loading = false; } } function reloadData() { - // Reset y recargar desde el principio window.location.reload(); } - function handleCreateClick() { - showCreateDialog = true; - } - function handleSuccess() { - // Recargar datos después de crear/editar/eliminar reloadData(); } - // Crear columnas con el callback onSuccess + useShortcuts('Contenedores', [ + { key: 'Alt+Shift+R', description: 'Actualizar Lista', action: reloadData } + ]); + const columns = createColumns(handleSuccess); -
- -
-
-

Contenedores

+
+ +
+
+

+ Contenedores +

- Gestiona los tipos de contenedores disponibles + Gestiona los tipos de contenedores disponibles en el sistema

- +
+ +
+
+ + +
+
+ Búsqueda General + +
- {#if error} - - - Error - {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 6a66336f..e3330243 100644 --- a/frontend/src/routes/dashboard/reference_data/countries/+page.svelte +++ b/frontend/src/routes/dashboard/reference_data/countries/+page.svelte @@ -3,9 +3,10 @@ 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 CreateEditDialog from '$lib/components/dashboard/reference_data/countries/create-edit-dialog.svelte'; import { Button } from '$lib/components/ui/button'; - import { Plus, RefreshCw } from 'lucide-svelte'; + import { Input } from '$lib/components/ui/input'; + import { RefreshCw } from 'lucide-svelte'; + import { page } from '$app/stores'; import type { PageData } from './$types'; import { useShortcuts } from '$lib/hooks/use-shortcuts'; import { obtenerAtajosLista } from '$lib/config/shortcuts/dashboard/reference_data/countries/list'; @@ -14,14 +15,10 @@ // Los datos iniciales vienen del servidor let { data }: { data: PageData } = $props(); - // Estado para el diálogo de crear - let showCreateDialog = $state(false); - // Atajos useShortcuts( 'Lista Países', obtenerAtajosLista({ - manejarNuevo: () => (showCreateDialog = true), manejarActualizar: reloadData }) ); @@ -64,6 +61,37 @@ let hasMore = $derived(allItems.length < totalItems); let error = $state(data.error || null); + // Filtros + let searchQuery = $state($page.url.searchParams.get('search') || ''); + let timeout: ReturnType; + + function handleSearch() { + if (!browser) return; + clearTimeout(timeout); + timeout = setTimeout(async () => { + loading = true; + try { + const response = await countriesApi.list(1, pageSize, searchQuery); + if (!response.error && response.data) { + allItems = response.data.items; + currentPage = 1; + totalItems = response.data.total; + } + } catch (e) { + console.error('Error aplicando filtros:', e); + } finally { + loading = false; + } + + // Actualizar URL silenciosamente para mantener estado + const url = new URL($page.url); + if (searchQuery) url.searchParams.set('search', searchQuery); + else url.searchParams.delete('search'); + + history.replaceState(history.state, '', url); + }, 500); + } + async function loadMore() { if (loading || !hasMore) return; @@ -71,7 +99,7 @@ error = null; try { - const response = await countriesApi.list(currentPage + 1, pageSize); + const response = await countriesApi.list(currentPage + 1, pageSize, searchQuery); if (response.error) { console.error('📊 [Page] Error en loadMore:', response.error, 'Status:', response.status); @@ -108,10 +136,6 @@ window.location.reload(); } - function handleCreateClick() { - showCreateDialog = true; - } - function handleSuccess() { // Recargar datos después de crear/editar/eliminar reloadData(); @@ -121,33 +145,46 @@ const columns = createColumns(handleSuccess); -
-
-
-

Países

+
+ +
+
+

+ Países +

Gestiona los países disponibles en el sistema

-
- - +
+
+ + +
+
+ Búsqueda General +
{#if error} -
+
{error}
{/if} -
+ +
- - 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 b546fb2a..7fbafdb6 100644 --- a/frontend/src/routes/dashboard/reference_data/currency_types/+page.svelte +++ b/frontend/src/routes/dashboard/reference_data/currency_types/+page.svelte @@ -3,55 +3,29 @@ 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 CreateEditDialog from '$lib/components/dashboard/reference_data/currency_types/create-edit-dialog.svelte'; import { Button } from '$lib/components/ui/button'; - import { Plus, RefreshCw } from 'lucide-svelte'; - import type { PageData } from './$types'; - import { useShortcuts } from '$lib/hooks/use-shortcuts'; - import { obtenerAtajosLista } from '$lib/config/shortcuts/dashboard/reference_data/currency_types/list'; + import { Input } from '$lib/components/ui/input'; + import { page } from '$app/stores'; import { browser } from '$app/environment'; + import { RefreshCw } from 'lucide-svelte'; + import { useShortcuts } from '$lib/hooks/use-shortcuts'; + import type { PageData } from './$types'; // Los datos iniciales vienen del servidor let { data }: { data: PageData } = $props(); - - // Estado para el diálogo de crear - let showCreateDialog = $state(false); - // Atajos - useShortcuts( - 'Lista Tipos de Moneda', - obtenerAtajosLista({ - manejarNuevo: () => (showCreateDialog = true), - manejarActualizar: reloadData - }) - ); - - // Sincronizar token de cookies a localStorage al montar el componente + // Sincronizar token de cookies onMount(() => { if (browser) { - // Función para obtener el valor de una cookie const getCookie = (name: string): string | null => { const value = `; ${document.cookie}`; const parts = value.split(`; ${name}=`); if (parts.length === 2) return parts.pop()?.split(';').shift() || null; return null; }; - - // Verificar si hay token en las cookies const cookieToken = getCookie('access_token'); const localToken = localStorage.getItem('access_token'); - - if (cookieToken && cookieToken !== localToken) { - localStorage.setItem('access_token', cookieToken); - } - - // También sincronizar refresh_token si existe - const cookieRefreshToken = getCookie('refresh_token'); - const localRefreshToken = localStorage.getItem('refresh_token'); - - if (cookieRefreshToken && cookieRefreshToken !== localRefreshToken) { - localStorage.setItem('refresh_token', cookieRefreshToken); - } + if (cookieToken && cookieToken !== localToken) localStorage.setItem('access_token', cookieToken); } }); @@ -64,98 +38,116 @@ let hasMore = $derived(allItems.length < totalItems); let error = $state(data.error || null); + // Filtros + let searchQuery = $state($page.url.searchParams.get('search') || ''); + let timeout: ReturnType; + + function handleSearch() { + if (!browser) return; + clearTimeout(timeout); + timeout = setTimeout(async () => { + loading = true; + try { + const response = await currencyTypesApi.list(1, pageSize, searchQuery); + if (!response.error && response.data) { + allItems = response.data.items; + currentPage = 1; + totalItems = response.data.total; + } + } catch (e) { + console.error('Error aplicando filtros:', e); + } finally { + loading = false; + } + const url = new URL($page.url); + if (searchQuery) url.searchParams.set('search', searchQuery); + else url.searchParams.delete('search'); + history.replaceState(history.state, '', url); + }, 500); + } + async function loadMore() { if (loading || !hasMore) return; - loading = true; error = null; - - try { - const response = await currencyTypesApi.list(currentPage + 1, pageSize); - + try { + const response = await currencyTypesApi.list(currentPage + 1, pageSize, searchQuery); if (response.error) { - console.error('📊 [Page] Error en loadMore:', response.error, 'Status:', response.status); - - // Si es un error de autenticación (401 o 403) y no se pudo refrescar, mostrar mensaje específico if (response.status === 401 || response.status === 403) { error = 'Sesión expirada. Recargando página...'; - // Recargar automáticamente después de 2 segundos - setTimeout(() => { - window.location.reload(); - }, 2000); + setTimeout(() => window.location.reload(), 2000); } else { error = response.error; } return; } - - if (response.data?.items) { - // Agregar los nuevos items al array existente + if (response.data?.items) { allItems = [...allItems, ...response.data.items]; currentPage++; totalItems = response.data.total; } } catch (e) { error = 'Error cargando más datos'; - console.error('📊 [Page] Error loading more:', e); } finally { loading = false; } } function reloadData() { - // Reset y recargar desde el principio window.location.reload(); } - function handleCreateClick() { - showCreateDialog = true; - } - function handleSuccess() { - // Recargar datos después de crear/editar/eliminar reloadData(); } - // Crear columnas con el callback onSuccess + useShortcuts('Tipos de Moneda', [ + { key: 'Alt+Shift+R', description: 'Actualizar Lista', action: reloadData } + ]); + const columns = createColumns(handleSuccess); -
-
-
-

Tipos de Moneda

+
+ +
+
+

+ Tipos de Moneda +

Gestiona los tipos de moneda disponibles en el sistema

-
- - +
+
+ + +
+
+ Búsqueda General +
{#if error} -
+
{error}
{/if} -
- + +
+
- - 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 4c59e6a0..473e8157 100644 --- a/frontend/src/routes/dashboard/reference_data/customs_sections/+page.svelte +++ b/frontend/src/routes/dashboard/reference_data/customs_sections/+page.svelte @@ -3,46 +3,29 @@ 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 CreateEditDialog from '$lib/components/dashboard/reference_data/customs_sections/create-edit-dialog.svelte'; - import * as Card from '$lib/components/ui/card'; import { Button } from '$lib/components/ui/button'; - import type { PageData } from './$types'; + import { Input } from '$lib/components/ui/input'; + import { page } from '$app/stores'; import { browser } from '$app/environment'; - import { Plus, RefreshCw } from 'lucide-svelte'; + import { RefreshCw } from 'lucide-svelte'; import { useShortcuts } from '$lib/hooks/use-shortcuts'; + import type { PageData } from './$types'; // Los datos iniciales vienen del servidor let { data }: { data: PageData } = $props(); - // Estado para el diálogo de crear - let showCreateDialog = $state(false); - - // Sincronizar token de cookies a localStorage al montar el componente + // Sincronizar token de cookies onMount(() => { if (browser) { - // Función para obtener el valor de una cookie const getCookie = (name: string): string | null => { const value = `; ${document.cookie}`; const parts = value.split(`; ${name}=`); if (parts.length === 2) return parts.pop()?.split(';').shift() || null; return null; }; - - // Verificar si hay token en las cookies const cookieToken = getCookie('access_token'); const localToken = localStorage.getItem('access_token'); - - if (cookieToken && cookieToken !== localToken) { - localStorage.setItem('access_token', cookieToken); - } - - // También sincronizar refresh_token si existe - const cookieRefreshToken = getCookie('refresh_token'); - const localRefreshToken = localStorage.getItem('refresh_token'); - - if (cookieRefreshToken && cookieRefreshToken !== localRefreshToken) { - localStorage.setItem('refresh_token', cookieRefreshToken); - } + if (cookieToken && cookieToken !== localToken) localStorage.setItem('access_token', cookieToken); } }); @@ -55,122 +38,116 @@ let hasMore = $derived(allItems.length < totalItems); let error = $state(data.error || null); + // Filtros + let searchQuery = $state($page.url.searchParams.get('search') || ''); + let timeout: ReturnType; + + function handleSearch() { + if (!browser) return; + clearTimeout(timeout); + timeout = setTimeout(async () => { + loading = true; + try { + const response = await customsSectionsApi.list(1, pageSize, searchQuery); + if (!response.error && response.data) { + allItems = response.data.items; + currentPage = 1; + totalItems = response.data.total; + } + } catch (e) { + console.error('Error aplicando filtros:', e); + } finally { + loading = false; + } + const url = new URL($page.url); + if (searchQuery) url.searchParams.set('search', searchQuery); + else url.searchParams.delete('search'); + history.replaceState(history.state, '', url); + }, 500); + } + async function loadMore() { if (loading || !hasMore) return; - loading = true; error = null; - try { - const response = await customsSectionsApi.list(currentPage + 1, pageSize); - + const response = await customsSectionsApi.list(currentPage + 1, pageSize, searchQuery); if (response.error) { - console.error('📊 [Page] Error en loadMore:', response.error, 'Status:', response.status); - - // Si es un error de autenticación (401 o 403) y no se pudo refrescar, mostrar mensaje específico if (response.status === 401 || response.status === 403) { error = 'Sesión expirada. Recargando página...'; - // Recargar automáticamente después de 2 segundos - setTimeout(() => { - window.location.reload(); - }, 2000); + setTimeout(() => window.location.reload(), 2000); } else { error = response.error; } return; } - if (response.data?.items) { - // Agregar los nuevos items al array existente allItems = [...allItems, ...response.data.items]; currentPage++; totalItems = response.data.total; } } catch (e) { error = 'Error cargando más datos'; - console.error('📊 [Page] Error loading more:', e); } finally { loading = false; } } function reloadData() { - // Reset y recargar desde el principio window.location.reload(); } - function handleCreateClick() { - showCreateDialog = true; - } - function handleSuccess() { - // Recargar datos después de crear/editar/eliminar reloadData(); } - // Keyboard Shortcuts useShortcuts('Secciones Aduanales', [ - { - key: 'Alt+Shift+N', - description: 'Nueva Sección', - action: handleCreateClick - }, - { - key: 'Alt+Shift+R', - description: 'Actualizar Lista', - action: reloadData - } + { key: 'Alt+Shift+R', description: 'Actualizar Lista', action: reloadData } ]); - // Crear columnas con el callback onSuccess const columns = createColumns(handleSuccess); -
- -
-
-

Secciones Aduanales

-

Gestiona las secciones aduanales del sistema

+
+ +
+
+

+ Secciones Aduanales +

+

+ Gestiona las secciones aduanales del sistema +

+
+
+ +
+
+ + +
+
+ Búsqueda General +
-
- {#if error} - - - Error - {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 7055ef57..409c3a09 100644 --- a/frontend/src/routes/dashboard/reference_data/customs_warehouses/+page.svelte +++ b/frontend/src/routes/dashboard/reference_data/customs_warehouses/+page.svelte @@ -3,55 +3,29 @@ 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 CreateEditDialog from '$lib/components/dashboard/reference_data/customs_warehouses/create-edit-dialog.svelte'; import { Button } from '$lib/components/ui/button'; - import type { PageData } from './$types'; - import { useShortcuts } from '$lib/hooks/use-shortcuts'; - import { obtenerAtajosLista } from '$lib/config/shortcuts/dashboard/reference_data/customs_warehouses/list'; + import { Input } from '$lib/components/ui/input'; + import { page } from '$app/stores'; import { browser } from '$app/environment'; - import { Plus, RefreshCw } from 'lucide-svelte'; + import { RefreshCw } from 'lucide-svelte'; + import { useShortcuts } from '$lib/hooks/use-shortcuts'; + import type { PageData } from './$types'; // Los datos iniciales vienen del servidor let { data }: { data: PageData } = $props(); - - // Estado para el diálogo de crear - let showCreateDialog = $state(false); - // Atajos - useShortcuts( - 'Lista Almacenes Aduanales', - obtenerAtajosLista({ - manejarNuevo: () => (showCreateDialog = true), - manejarActualizar: reloadData - }) - ); - - // Sincronizar token de cookies a localStorage al montar el componente + // Sincronizar token de cookies onMount(() => { if (browser) { - // Función para obtener el valor de una cookie const getCookie = (name: string): string | null => { const value = `; ${document.cookie}`; const parts = value.split(`; ${name}=`); if (parts.length === 2) return parts.pop()?.split(';').shift() || null; return null; }; - - // Verificar si hay token en las cookies const cookieToken = getCookie('access_token'); const localToken = localStorage.getItem('access_token'); - - if (cookieToken && cookieToken !== localToken) { - localStorage.setItem('access_token', cookieToken); - } - - // También sincronizar refresh_token si existe - const cookieRefreshToken = getCookie('refresh_token'); - const localRefreshToken = localStorage.getItem('refresh_token'); - - if (cookieRefreshToken && cookieRefreshToken !== localRefreshToken) { - localStorage.setItem('refresh_token', cookieRefreshToken); - } + if (cookieToken && cookieToken !== localToken) localStorage.setItem('access_token', cookieToken); } }); @@ -64,98 +38,116 @@ let hasMore = $derived(allItems.length < totalItems); let error = $state(data.error || null); + // Filtros + let searchQuery = $state($page.url.searchParams.get('search') || ''); + let timeout: ReturnType; + + function handleSearch() { + if (!browser) return; + clearTimeout(timeout); + timeout = setTimeout(async () => { + loading = true; + try { + const response = await customsWarehousesApi.list(1, pageSize, searchQuery); + if (!response.error && response.data) { + allItems = response.data.items; + currentPage = 1; + totalItems = response.data.total; + } + } catch (e) { + console.error('Error aplicando filtros:', e); + } finally { + loading = false; + } + const url = new URL($page.url); + if (searchQuery) url.searchParams.set('search', searchQuery); + else url.searchParams.delete('search'); + history.replaceState(history.state, '', url); + }, 500); + } + async function loadMore() { if (loading || !hasMore) return; - loading = true; error = null; - - try { - const response = await customsWarehousesApi.list(currentPage + 1, pageSize); - + try { + const response = await customsWarehousesApi.list(currentPage + 1, pageSize, searchQuery); if (response.error) { - console.error('📊 [Page] Error en loadMore:', response.error, 'Status:', response.status); - - // Si es un error de autenticación (401 o 403) y no se pudo refrescar, mostrar mensaje específico if (response.status === 401 || response.status === 403) { error = 'Sesión expirada. Recargando página...'; - // Recargar automáticamente después de 2 segundos - setTimeout(() => { - window.location.reload(); - }, 2000); + setTimeout(() => window.location.reload(), 2000); } else { error = response.error; } return; } - - if (response.data?.items) { - // Agregar los nuevos items al array existente + if (response.data?.items) { allItems = [...allItems, ...response.data.items]; currentPage++; totalItems = response.data.total; } } catch (e) { error = 'Error cargando más datos'; - console.error('📊 [Page] Error loading more:', e); } finally { loading = false; } } function reloadData() { - // Reset y recargar desde el principio window.location.reload(); } - function handleCreateClick() { - showCreateDialog = true; - } - function handleSuccess() { - // Recargar datos después de crear/editar/eliminar reloadData(); } - // Crear columnas con el callback onSuccess + useShortcuts('Almacenes Aduanales', [ + { key: 'Alt+Shift+R', description: 'Actualizar Lista', action: reloadData } + ]); + const columns = createColumns(handleSuccess); -
-
-
-

Recintos Fiscalizados

+
+ +
+
+

+ Recintos Fiscalizados +

Gestiona los recintos fiscalizados del sistema aduanal

-
- - +
+
+ + +
+
+ Búsqueda General +
{#if error} -
+
{error}
{/if} -
- + +
+
- - diff --git a/frontend/src/routes/dashboard/reference_data/incoterms/+page.server.ts b/frontend/src/routes/dashboard/reference_data/incoterms/+page.server.ts index 776fe196..0527ad0a 100644 --- a/frontend/src/routes/dashboard/reference_data/incoterms/+page.server.ts +++ b/frontend/src/routes/dashboard/reference_data/incoterms/+page.server.ts @@ -18,13 +18,20 @@ export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => { } try { - // Obtener parámetros de paginación de la URL + // Obtener parámetros de paginación y filtros de la URL const page = parseInt(url.searchParams.get('page') || '1'); const pageSize = parseInt(url.searchParams.get('page_size') || '50'); + const code = url.searchParams.get('code') || ''; + const description = url.searchParams.get('description') || ''; + + // Construir URL con filtros + let endpoint = `v1/public/reference_data/incoterms/?page=${page}&page_size=${pageSize}`; + if (code) endpoint += `&code=${encodeURIComponent(code)}`; + if (description) endpoint += `&description=${encodeURIComponent(description)}`; // Usar authenticatedFetch para manejar automáticamente el refresh de tokens const response = await authenticatedFetch( - `v1/public/reference_data/incoterms/?page=${page}&page_size=${pageSize}`, + endpoint, {}, cookies, fetch diff --git a/frontend/src/routes/dashboard/reference_data/incoterms/+page.svelte b/frontend/src/routes/dashboard/reference_data/incoterms/+page.svelte index 9a1b417c..fe2846fd 100644 --- a/frontend/src/routes/dashboard/reference_data/incoterms/+page.svelte +++ b/frontend/src/routes/dashboard/reference_data/incoterms/+page.svelte @@ -2,29 +2,75 @@ import { page } from '$app/stores'; import { goto } from '$app/navigation'; import { browser } from '$app/environment'; + 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 CreateEditDialog from '$lib/components/dashboard/reference_data/incoterms/create-edit-dialog.svelte'; import { Button } from '$lib/components/ui/button'; import { Input } from '$lib/components/ui/input'; - import { Plus } from 'lucide-svelte'; + import { RefreshCw, Plus } from 'lucide-svelte'; import { useShortcuts } from '$lib/hooks/use-shortcuts'; import { obtenerAtajosLista } from '$lib/config/shortcuts/dashboard/reference_data/incoterms/list'; import type { PageData } from './$types'; let { data }: { data: PageData } = $props(); - let createDialogOpen = $state(false); - // Atajos useShortcuts( 'Lista Incoterms', obtenerAtajosLista({ - manejarNuevo: () => (createDialogOpen = true), - manejarActualizar: handleSuccess + manejarActualizar: reloadData }) ); + // Estado para infinite scroll + let allItems = $state(data.items || []); + let currentPage = $state(data.page || 1); + let pageSize = $state(50); + let totalItems = $state(data.total || 0); + let loading = $state(false); + let hasMore = $derived(allItems.length < totalItems); + let error = $state(data.error || null); + + async function loadMore() { + if (loading || !hasMore) return; + + loading = true; + error = null; + + try { + const response = await incotermsApi.list(currentPage + 1, pageSize, searchCode, searchDesc); + + if (response.error) { + console.error('📊 [Page] Error en loadMore:', response.error, 'Status:', response.status); + + if (response.status === 401 || response.status === 403) { + error = 'Sesión expirada. Recargando página...'; + setTimeout(() => { + window.location.reload(); + }, 2000); + } else { + error = response.error; + } + return; + } + + if (response.data?.items) { + allItems = [...allItems, ...response.data.items]; + currentPage++; + totalItems = response.data.total; + } + } catch (e) { + error = 'Error cargando más datos'; + console.error('📊 [Page] Error loading more:', e); + } finally { + loading = false; + } + } + + function reloadData() { + window.location.reload(); + } + // Filtros let searchCode = $state($page.url.searchParams.get('code') || ''); let searchDesc = $state($page.url.searchParams.get('description') || ''); @@ -33,7 +79,22 @@ function handleSearch() { if (!browser) return; clearTimeout(timeout); - timeout = setTimeout(() => { + timeout = setTimeout(async () => { + loading = true; + try { + const response = await incotermsApi.list(1, pageSize, searchCode, searchDesc); + if (!response.error && response.data) { + allItems = response.data.items; + currentPage = 1; + totalItems = response.data.total; + } + } catch (e) { + console.error('Error aplicando filtros:', e); + } finally { + loading = false; + } + + // Actualizar URL silenciosamente para mantener estado const url = new URL($page.url); if (searchCode) url.searchParams.set('code', searchCode); else url.searchParams.delete('code'); @@ -41,8 +102,7 @@ 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); } @@ -52,44 +112,61 @@ } -
-
-
-

Incoterms

+
+ +
+
+

+ Incoterms +

- Catálogo de Incoterms + Catálogo de términos internacionales de comercio

-
+
+
+ +
-
-
+ +
+
+ Clave
-
+
+ Descripción
-
+ {#if error} +
+ {error} +
+ {/if} + + +
- -
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 f615c7b3..65f13791 100644 --- a/frontend/src/routes/dashboard/reference_data/invoice_types/+page.svelte +++ b/frontend/src/routes/dashboard/reference_data/invoice_types/+page.svelte @@ -3,55 +3,29 @@ 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 CreateEditDialog from '$lib/components/dashboard/reference_data/invoice_types/create-edit-dialog.svelte'; import { Button } from '$lib/components/ui/button'; - import { Plus, RefreshCw } from 'lucide-svelte'; - import type { PageData } from './$types'; - import { useShortcuts } from '$lib/hooks/use-shortcuts'; - import { obtenerAtajosLista } from '$lib/config/shortcuts/dashboard/reference_data/invoice_types/list'; + import { Input } from '$lib/components/ui/input'; + import { page } from '$app/stores'; import { browser } from '$app/environment'; + import { RefreshCw } from 'lucide-svelte'; + import { useShortcuts } from '$lib/hooks/use-shortcuts'; + import type { PageData } from './$types'; // Los datos iniciales vienen del servidor let { data }: { data: PageData } = $props(); - - // Estado para el diálogo de crear - let showCreateDialog = $state(false); - // Atajos - useShortcuts( - 'Lista Tipos de Factura', - obtenerAtajosLista({ - manejarNuevo: () => (showCreateDialog = true), - manejarActualizar: reloadData - }) - ); - - // Sincronizar token de cookies a localStorage al montar el componente + // Sincronizar token de cookies onMount(() => { if (browser) { - // Función para obtener el valor de una cookie const getCookie = (name: string): string | null => { const value = `; ${document.cookie}`; const parts = value.split(`; ${name}=`); if (parts.length === 2) return parts.pop()?.split(';').shift() || null; return null; }; - - // Verificar si hay token en las cookies const cookieToken = getCookie('access_token'); const localToken = localStorage.getItem('access_token'); - - if (cookieToken && cookieToken !== localToken) { - localStorage.setItem('access_token', cookieToken); - } - - // También sincronizar refresh_token si existe - const cookieRefreshToken = getCookie('refresh_token'); - const localRefreshToken = localStorage.getItem('refresh_token'); - - if (cookieRefreshToken && cookieRefreshToken !== localRefreshToken) { - localStorage.setItem('refresh_token', cookieRefreshToken); - } + if (cookieToken && cookieToken !== localToken) localStorage.setItem('access_token', cookieToken); } }); @@ -64,98 +38,116 @@ let hasMore = $derived(allItems.length < totalItems); let error = $state(data.error || null); + // Filtros + let searchQuery = $state($page.url.searchParams.get('search') || ''); + let timeout: ReturnType; + + function handleSearch() { + if (!browser) return; + clearTimeout(timeout); + timeout = setTimeout(async () => { + loading = true; + try { + const response = await invoiceTypesApi.list(1, pageSize, undefined, searchQuery); + if (!response.error && response.data) { + allItems = response.data.items; + currentPage = 1; + totalItems = response.data.total; + } + } catch (e) { + console.error('Error aplicando filtros:', e); + } finally { + loading = false; + } + const url = new URL($page.url); + if (searchQuery) url.searchParams.set('search', searchQuery); + else url.searchParams.delete('search'); + history.replaceState(history.state, '', url); + }, 500); + } + async function loadMore() { if (loading || !hasMore) return; - loading = true; error = null; - - try { - const response = await invoiceTypesApi.list(currentPage + 1, pageSize); - + try { + const response = await invoiceTypesApi.list(currentPage + 1, pageSize, undefined, searchQuery); if (response.error) { - console.error('📊 [Page] Error en loadMore:', response.error, 'Status:', response.status); - - // Si es un error de autenticación (401 o 403) y no se pudo refrescar, mostrar mensaje específico if (response.status === 401 || response.status === 403) { error = 'Sesión expirada. Recargando página...'; - // Recargar automáticamente después de 2 segundos - setTimeout(() => { - window.location.reload(); - }, 2000); + setTimeout(() => window.location.reload(), 2000); } else { error = response.error; } return; } - - if (response.data?.items) { - // Agregar los nuevos items al array existente + if (response.data?.items) { allItems = [...allItems, ...response.data.items]; currentPage++; totalItems = response.data.total; } } catch (e) { error = 'Error cargando más datos'; - console.error('📊 [Page] Error loading more:', e); } finally { loading = false; } } function reloadData() { - // Reset y recargar desde el principio window.location.reload(); } - function handleCreateClick() { - showCreateDialog = true; - } - function handleSuccess() { - // Recargar datos después de crear/editar/eliminar reloadData(); } - // Crear columnas con el callback onSuccess + useShortcuts('Tipos de Factura', [ + { key: 'Alt+Shift+R', description: 'Actualizar Lista', action: reloadData } + ]); + const columns = createColumns(handleSuccess); -
-
-
-

Tipos de Factura

+
+ +
+
+

+ Tipos de Factura +

- Gestiona los tipos de facturas del sistema + Gestiona los tipos de facturas disponibles en el sistema

-
- - +
+
+ + +
+
+ Búsqueda General +
{#if error} -
+
{error}
{/if} -
- + +
+
- - 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 1847f6e2..d13df004 100644 --- a/frontend/src/routes/dashboard/reference_data/material_types/+page.svelte +++ b/frontend/src/routes/dashboard/reference_data/material_types/+page.svelte @@ -3,56 +3,29 @@ 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 CreateEditDialog from '$lib/components/dashboard/reference_data/material_types/create-edit-dialog.svelte'; - import * as Card from '$lib/components/ui/card'; import { Button } from '$lib/components/ui/button'; - import type { PageData } from './$types'; - import { useShortcuts } from '$lib/hooks/use-shortcuts'; - import { obtenerAtajosLista } from '$lib/config/shortcuts/dashboard/reference_data/material_types/list'; + import { Input } from '$lib/components/ui/input'; + import { page } from '$app/stores'; import { browser } from '$app/environment'; - import { Plus, RefreshCw } from 'lucide-svelte'; + import { RefreshCw } from 'lucide-svelte'; + import { useShortcuts } from '$lib/hooks/use-shortcuts'; + import type { PageData } from './$types'; // Los datos iniciales vienen del servidor let { data }: { data: PageData } = $props(); - - // Estado para el diálogo de crear - let showCreateDialog = $state(false); - // Atajos - useShortcuts( - 'Lista Tipos de Material', - obtenerAtajosLista({ - manejarNuevo: () => (showCreateDialog = true), - manejarActualizar: reloadData - }) - ); - - // Sincronizar token de cookies a localStorage al montar el componente + // Sincronizar token de cookies onMount(() => { if (browser) { - // Función para obtener el valor de una cookie const getCookie = (name: string): string | null => { const value = `; ${document.cookie}`; const parts = value.split(`; ${name}=`); if (parts.length === 2) return parts.pop()?.split(';').shift() || null; return null; }; - - // Verificar si hay token en las cookies const cookieToken = getCookie('access_token'); const localToken = localStorage.getItem('access_token'); - - if (cookieToken && cookieToken !== localToken) { - localStorage.setItem('access_token', cookieToken); - } - - // También sincronizar refresh_token si existe - const cookieRefreshToken = getCookie('refresh_token'); - const localRefreshToken = localStorage.getItem('refresh_token'); - - if (cookieRefreshToken && cookieRefreshToken !== localRefreshToken) { - localStorage.setItem('refresh_token', cookieRefreshToken); - } + if (cookieToken && cookieToken !== localToken) localStorage.setItem('access_token', cookieToken); } }); @@ -65,116 +38,116 @@ let hasMore = $derived(allItems.length < totalItems); let error = $state(data.error || null); + // Filtros + let searchQuery = $state($page.url.searchParams.get('search') || ''); + let timeout: ReturnType; + + function handleSearch() { + if (!browser) return; + clearTimeout(timeout); + timeout = setTimeout(async () => { + loading = true; + try { + const response = await materialTypesApi.list(1, pageSize, undefined, searchQuery); + if (!response.error && response.data) { + allItems = response.data.items; + currentPage = 1; + totalItems = response.data.total; + } + } catch (e) { + console.error('Error aplicando filtros:', e); + } finally { + loading = false; + } + const url = new URL($page.url); + if (searchQuery) url.searchParams.set('search', searchQuery); + else url.searchParams.delete('search'); + history.replaceState(history.state, '', url); + }, 500); + } + async function loadMore() { if (loading || !hasMore) return; - loading = true; error = null; - - try { - const response = await materialTypesApi.list(currentPage + 1, pageSize); - + try { + const response = await materialTypesApi.list(currentPage + 1, pageSize, undefined, searchQuery); if (response.error) { - console.error('📊 [Page] Error en loadMore:', response.error, 'Status:', response.status); - - // Si es un error de autenticación (401 o 403) y no se pudo refrescar, mostrar mensaje específico if (response.status === 401 || response.status === 403) { error = 'Sesión expirada. Recargando página...'; - // Recargar automáticamente después de 2 segundos - setTimeout(() => { - window.location.reload(); - }, 2000); + setTimeout(() => window.location.reload(), 2000); } else { error = response.error; } return; } - - if (response.data?.items) { - // Agregar los nuevos items al array existente + if (response.data?.items) { allItems = [...allItems, ...response.data.items]; currentPage++; totalItems = response.data.total; } } catch (e) { error = 'Error cargando más datos'; - console.error('📊 [Page] Error loading more:', e); } finally { loading = false; } } function reloadData() { - // Reset y recargar desde el principio window.location.reload(); } - function handleCreateClick() { - showCreateDialog = true; - } - function handleSuccess() { - // Recargar datos después de crear/editar/eliminar reloadData(); } - // Crear columnas con el callback onSuccess + useShortcuts('Tipos de Material', [ + { key: 'Alt+Shift+R', description: 'Actualizar Lista', action: reloadData } + ]); + const columns = createColumns(handleSuccess); -
- -
-
-

Tipos de Material

+
+ +
+
+

+ Tipos de Material +

- Gestiona los tipos de materiales del sistema + Gestiona los tipos de materiales disponibles en el sistema

- +
+ +
+
+ + +
+
+ Búsqueda General + +
- {#if error} - - - Error - {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 53623210..c25f8372 100644 --- a/frontend/src/routes/dashboard/reference_data/payment_methods/+page.svelte +++ b/frontend/src/routes/dashboard/reference_data/payment_methods/+page.svelte @@ -3,46 +3,29 @@ 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 CreateEditDialog from '$lib/components/dashboard/reference_data/payment_methods/create-edit-dialog.svelte'; - import * as Card from '$lib/components/ui/card'; import { Button } from '$lib/components/ui/button'; - import type { PageData } from './$types'; + import { Input } from '$lib/components/ui/input'; + import { page } from '$app/stores'; import { browser } from '$app/environment'; - import { Plus, RefreshCw } from 'lucide-svelte'; + import { RefreshCw } from 'lucide-svelte'; import { useShortcuts } from '$lib/hooks/use-shortcuts'; + import type { PageData } from './$types'; // Los datos iniciales vienen del servidor let { data }: { data: PageData } = $props(); - // Estado para el diálogo de crear - let showCreateDialog = $state(false); - - // Sincronizar token de cookies a localStorage al montar el componente + // Sincronizar token de cookies onMount(() => { if (browser) { - // Función para obtener el valor de una cookie const getCookie = (name: string): string | null => { const value = `; ${document.cookie}`; const parts = value.split(`; ${name}=`); if (parts.length === 2) return parts.pop()?.split(';').shift() || null; return null; }; - - // Verificar si hay token en las cookies const cookieToken = getCookie('access_token'); const localToken = localStorage.getItem('access_token'); - - if (cookieToken && cookieToken !== localToken) { - localStorage.setItem('access_token', cookieToken); - } - - // También sincronizar refresh_token si existe - const cookieRefreshToken = getCookie('refresh_token'); - const localRefreshToken = localStorage.getItem('refresh_token'); - - if (cookieRefreshToken && cookieRefreshToken !== localRefreshToken) { - localStorage.setItem('refresh_token', cookieRefreshToken); - } + if (cookieToken && cookieToken !== localToken) localStorage.setItem('access_token', cookieToken); } }); @@ -55,122 +38,116 @@ let hasMore = $derived(allItems.length < totalItems); let error = $state(data.error || null); + // Filtros + let searchQuery = $state($page.url.searchParams.get('search') || ''); + let timeout: ReturnType; + + function handleSearch() { + if (!browser) return; + clearTimeout(timeout); + timeout = setTimeout(async () => { + loading = true; + try { + const response = await paymentMethodsApi.list(1, pageSize, searchQuery); + if (!response.error && response.data) { + allItems = response.data.items; + currentPage = 1; + totalItems = response.data.total; + } + } catch (e) { + console.error('Error aplicando filtros:', e); + } finally { + loading = false; + } + const url = new URL($page.url); + if (searchQuery) url.searchParams.set('search', searchQuery); + else url.searchParams.delete('search'); + history.replaceState(history.state, '', url); + }, 500); + } + async function loadMore() { if (loading || !hasMore) return; - loading = true; error = null; - try { - const response = await paymentMethodsApi.list(currentPage + 1, pageSize); - + const response = await paymentMethodsApi.list(currentPage + 1, pageSize, searchQuery); if (response.error) { - console.error('📊 [Page] Error en loadMore:', response.error, 'Status:', response.status); - - // Si es un error de autenticación (401 o 403) y no se pudo refrescar, mostrar mensaje específico if (response.status === 401 || response.status === 403) { error = 'Sesión expirada. Recargando página...'; - // Recargar automáticamente después de 2 segundos - setTimeout(() => { - window.location.reload(); - }, 2000); + setTimeout(() => window.location.reload(), 2000); } else { error = response.error; } return; } - if (response.data?.items) { - // Agregar los nuevos items al array existente allItems = [...allItems, ...response.data.items]; currentPage++; totalItems = response.data.total; } } catch (e) { error = 'Error cargando más datos'; - console.error('📊 [Page] Error loading more:', e); } finally { loading = false; } } function reloadData() { - // Reset y recargar desde el principio window.location.reload(); } - function handleCreateClick() { - showCreateDialog = true; - } - function handleSuccess() { - // Recargar datos después de crear/editar/eliminar reloadData(); } - // Keyboard Shortcuts useShortcuts('Métodos de Pago', [ - { - key: 'Alt+Shift+N', - description: 'Nuevo Método', - action: handleCreateClick - }, - { - key: 'Alt+Shift+R', - description: 'Actualizar Lista', - action: reloadData - } + { key: 'Alt+Shift+R', description: 'Actualizar Lista', action: reloadData } ]); - // Crear columnas con el callback onSuccess const columns = createColumns(handleSuccess); -
- -
-
-

Métodos de Pago

-

Gestiona las formas de pago disponibles en el sistema

+
+ +
+
+

+ Métodos de Pago +

+

+ Gestiona las formas de pago disponibles en el sistema +

+
+
+ +
+
+ + +
+
+ Búsqueda General +
-
- {#if error} - - - Error - {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 15db3620..cb541aee 100644 --- a/frontend/src/routes/dashboard/reference_data/pedimento_codes/+page.svelte +++ b/frontend/src/routes/dashboard/reference_data/pedimento_codes/+page.svelte @@ -3,46 +3,29 @@ 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 CreateEditDialog from '$lib/components/dashboard/reference_data/pedimento_codes/create-edit-dialog.svelte'; - import * as Card from '$lib/components/ui/card'; import { Button } from '$lib/components/ui/button'; - import { Plus, RefreshCw } from 'lucide-svelte'; + import { Input } from '$lib/components/ui/input'; + import { page } from '$app/stores'; + import { browser } from '$app/environment'; + import { RefreshCw } from 'lucide-svelte'; import { useShortcuts } from '$lib/hooks/use-shortcuts'; import type { PageData } from './$types'; - import { browser } from '$app/environment'; // Los datos iniciales vienen del servidor let { data }: { data: PageData } = $props(); - // Estado para el diálogo de crear - let showCreateDialog = $state(false); - - // Sincronizar token de cookies a localStorage al montar el componente + // Sincronizar token de cookies onMount(() => { if (browser) { - // Función para obtener el valor de una cookie const getCookie = (name: string): string | null => { const value = `; ${document.cookie}`; const parts = value.split(`; ${name}=`); if (parts.length === 2) return parts.pop()?.split(';').shift() || null; return null; }; - - // Verificar si hay token en las cookies const cookieToken = getCookie('access_token'); const localToken = localStorage.getItem('access_token'); - - if (cookieToken && cookieToken !== localToken) { - localStorage.setItem('access_token', cookieToken); - } - - // También sincronizar refresh_token si existe - const cookieRefreshToken = getCookie('refresh_token'); - const localRefreshToken = localStorage.getItem('refresh_token'); - - if (cookieRefreshToken && cookieRefreshToken !== localRefreshToken) { - localStorage.setItem('refresh_token', cookieRefreshToken); - } + if (cookieToken && cookieToken !== localToken) localStorage.setItem('access_token', cookieToken); } }); @@ -55,122 +38,116 @@ let hasMore = $derived(allItems.length < totalItems); let error = $state(data.error || null); + // Filtros + let searchQuery = $state($page.url.searchParams.get('search') || ''); + let timeout: ReturnType; + + function handleSearch() { + if (!browser) return; + clearTimeout(timeout); + timeout = setTimeout(async () => { + loading = true; + try { + const response = await pedimentoCodesApi.list(1, pageSize, searchQuery); + if (!response.error && response.data) { + allItems = response.data.items; + currentPage = 1; + totalItems = response.data.total; + } + } catch (e) { + console.error('Error aplicando filtros:', e); + } finally { + loading = false; + } + const url = new URL($page.url); + if (searchQuery) url.searchParams.set('search', searchQuery); + else url.searchParams.delete('search'); + history.replaceState(history.state, '', url); + }, 500); + } + async function loadMore() { if (loading || !hasMore) return; - loading = true; error = null; - try { - const response = await pedimentoCodesApi.list(currentPage + 1, pageSize); - + const response = await pedimentoCodesApi.list(currentPage + 1, pageSize, searchQuery); if (response.error) { - console.error('📊 [Page] Error en loadMore:', response.error, 'Status:', response.status); - - // Si es un error de autenticación (401 o 403) y no se pudo refrescar, mostrar mensaje específico if (response.status === 401 || response.status === 403) { error = 'Sesión expirada. Recargando página...'; - // Recargar automáticamente después de 2 segundos - setTimeout(() => { - window.location.reload(); - }, 2000); + setTimeout(() => window.location.reload(), 2000); } else { error = response.error; } return; } - if (response.data?.items) { - // Agregar los nuevos items al array existente allItems = [...allItems, ...response.data.items]; currentPage++; totalItems = response.data.total; } } catch (e) { error = 'Error cargando más datos'; - console.error('📊 [Page] Error loading more:', e); } finally { loading = false; } } function reloadData() { - // Reset y recargar desde el principio window.location.reload(); } - function handleCreateClick() { - showCreateDialog = true; - } - function handleSuccess() { - // Recargar datos después de crear/editar/eliminar reloadData(); } - // Keyboard Shortcuts useShortcuts('Claves de Pedimento', [ - { - key: 'Alt+Shift+N', - description: 'Nueva Clave', - action: handleCreateClick - }, - { - key: 'Alt+Shift+R', - description: 'Actualizar Lista', - action: reloadData - } + { key: 'Alt+Shift+R', description: 'Actualizar Lista', action: reloadData } ]); - // Crear columnas con el callback onSuccess const columns = createColumns(handleSuccess); -
- -
-
-

Claves de Pedimento

-

Gestiona las claves de pedimento del sistema aduanero

+
+ +
+
+

+ Claves de Pedimento +

+

+ Gestiona las claves de pedimento del sistema aduanero +

+
+
+ +
+
+ + +
+
+ Búsqueda General +
-
- {#if error} - - - Error - {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 e2222c2f..27a53484 100644 --- a/frontend/src/routes/dashboard/reference_data/pedimento_regimens/+page.svelte +++ b/frontend/src/routes/dashboard/reference_data/pedimento_regimens/+page.svelte @@ -3,46 +3,29 @@ 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 CreateEditDialog from '$lib/components/dashboard/reference_data/pedimento_regimens/create-edit-dialog.svelte'; - import * as Card from '$lib/components/ui/card'; import { Button } from '$lib/components/ui/button'; - import type { PageData } from './$types'; + import { Input } from '$lib/components/ui/input'; + import { page } from '$app/stores'; import { browser } from '$app/environment'; - import { Plus, RefreshCw } from 'lucide-svelte'; + import { RefreshCw } from 'lucide-svelte'; import { useShortcuts } from '$lib/hooks/use-shortcuts'; + import type { PageData } from './$types'; // Los datos iniciales vienen del servidor let { data }: { data: PageData } = $props(); - // Estado para el diálogo de crear - let showCreateDialog = $state(false); - - // Sincronizar token de cookies a localStorage al montar el componente + // Sincronizar token de cookies onMount(() => { if (browser) { - // Función para obtener el valor de una cookie const getCookie = (name: string): string | null => { const value = `; ${document.cookie}`; const parts = value.split(`; ${name}=`); if (parts.length === 2) return parts.pop()?.split(';').shift() || null; return null; }; - - // Verificar si hay token en las cookies const cookieToken = getCookie('access_token'); const localToken = localStorage.getItem('access_token'); - - if (cookieToken && cookieToken !== localToken) { - localStorage.setItem('access_token', cookieToken); - } - - // También sincronizar refresh_token si existe - const cookieRefreshToken = getCookie('refresh_token'); - const localRefreshToken = localStorage.getItem('refresh_token'); - - if (cookieRefreshToken && cookieRefreshToken !== localRefreshToken) { - localStorage.setItem('refresh_token', cookieRefreshToken); - } + if (cookieToken && cookieToken !== localToken) localStorage.setItem('access_token', cookieToken); } }); @@ -55,122 +38,116 @@ let hasMore = $derived(allItems.length < totalItems); let error = $state(data.error || null); + // Filtros + let searchQuery = $state($page.url.searchParams.get('search') || ''); + let timeout: ReturnType; + + function handleSearch() { + if (!browser) return; + clearTimeout(timeout); + timeout = setTimeout(async () => { + loading = true; + try { + const response = await pedimentoRegimensApi.list(1, pageSize, searchQuery); + if (!response.error && response.data) { + allItems = response.data.items; + currentPage = 1; + totalItems = response.data.total; + } + } catch (e) { + console.error('Error aplicando filtros:', e); + } finally { + loading = false; + } + const url = new URL($page.url); + if (searchQuery) url.searchParams.set('search', searchQuery); + else url.searchParams.delete('search'); + history.replaceState(history.state, '', url); + }, 500); + } + async function loadMore() { if (loading || !hasMore) return; - loading = true; error = null; - try { - const response = await pedimentoRegimensApi.list(currentPage + 1, pageSize); - + const response = await pedimentoRegimensApi.list(currentPage + 1, pageSize, searchQuery); if (response.error) { - console.error('📊 [Page] Error en loadMore:', response.error, 'Status:', response.status); - - // Si es un error de autenticación (401 o 403) y no se pudo refrescar, mostrar mensaje específico if (response.status === 401 || response.status === 403) { error = 'Sesión expirada. Recargando página...'; - // Recargar automáticamente después de 2 segundos - setTimeout(() => { - window.location.reload(); - }, 2000); + setTimeout(() => window.location.reload(), 2000); } else { error = response.error; } return; } - if (response.data?.items) { - // Agregar los nuevos items al array existente allItems = [...allItems, ...response.data.items]; currentPage++; totalItems = response.data.total; } } catch (e) { error = 'Error cargando más datos'; - console.error('📊 [Page] Error loading more:', e); } finally { loading = false; } } function reloadData() { - // Reset y recargar desde el principio window.location.reload(); } - function handleCreateClick() { - showCreateDialog = true; - } - function handleSuccess() { - // Recargar datos después de crear/editar/eliminar reloadData(); } - // Keyboard Shortcuts useShortcuts('Regímenes', [ - { - key: 'Alt+Shift+N', - description: 'Nuevo Régimen', - action: handleCreateClick - }, - { - key: 'Alt+Shift+R', - description: 'Actualizar Lista', - action: reloadData - } + { key: 'Alt+Shift+R', description: 'Actualizar Lista', action: reloadData } ]); - // Crear columnas con el callback onSuccess const columns = createColumns(handleSuccess); -
- -
-
-

Regímenes de Pedimento

-

Gestiona los regímenes aduaneros de pedimento

+
+ +
+
+

+ Regímenes +

+

+ Gestiona los regímenes aduaneros de pedimento +

+
+
+ +
+
+ + +
+
+ Búsqueda General +
-
- {#if error} - - - Error - {error} - - +
+ {error} +
{/if} - - - -
-
- Listado de Regímenes de Pedimento - - 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 f944f18f..f01672d4 100644 --- a/frontend/src/routes/dashboard/reference_data/sectors/+page.svelte +++ b/frontend/src/routes/dashboard/reference_data/sectors/+page.svelte @@ -4,56 +4,29 @@ 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 CreateEditDialog from '$lib/components/dashboard/reference_data/sectors/create-edit-dialog.svelte'; - import * as Card from '$lib/components/ui/card'; import { Button } from '$lib/components/ui/button'; - import { Plus, RefreshCw } from 'lucide-svelte'; - import type { PageData } from './$types'; - import { useShortcuts } from '$lib/hooks/use-shortcuts'; - import { obtenerAtajosLista } from '$lib/config/shortcuts/dashboard/reference_data/sectors/list'; + import { Input } from '$lib/components/ui/input'; + import { page } from '$app/stores'; import { browser } from '$app/environment'; + import { RefreshCw } from 'lucide-svelte'; + import { useShortcuts } from '$lib/hooks/use-shortcuts'; + import type { PageData } from './$types'; // Los datos iniciales vienen del servidor let { data }: { data: PageData } = $props(); - - // Estado para el diálogo de crear - let showCreateDialog = $state(false); - // Atajos - useShortcuts( - 'Lista Sectores', - obtenerAtajosLista({ - manejarNuevo: () => (showCreateDialog = true), - manejarActualizar: reloadData - }) - ); - - // Sincronizar token de cookies a localStorage al montar el componente + // Sincronizar token de cookies onMount(() => { if (browser) { - // Función para obtener el valor de una cookie const getCookie = (name: string): string | null => { const value = `; ${document.cookie}`; const parts = value.split(`; ${name}=`); if (parts.length === 2) return parts.pop()?.split(';').shift() || null; return null; }; - - // Verificar si hay token en las cookies const cookieToken = getCookie('access_token'); const localToken = localStorage.getItem('access_token'); - - if (cookieToken && cookieToken !== localToken) { - localStorage.setItem('access_token', cookieToken); - } - - // También sincronizar refresh_token si existe - const cookieRefreshToken = getCookie('refresh_token'); - const localRefreshToken = localStorage.getItem('refresh_token'); - - if (cookieRefreshToken && cookieRefreshToken !== localRefreshToken) { - localStorage.setItem('refresh_token', cookieRefreshToken); - } + if (cookieToken && cookieToken !== localToken) localStorage.setItem('access_token', cookieToken); } }); @@ -66,121 +39,139 @@ let hasMore = $derived(allItems.length < totalItems); let error = $state(data.error || null); + // Filtros + let searchQuery = $state($page.url.searchParams.get('search') || ''); + let timeout: ReturnType; + + function getActiveCompanyId(): number | null { + const fromStore = companyStore.activeCompany?.id; + if (fromStore) return fromStore; + if (!browser) return null; + const cookie = document.cookie + .split('; ') + .find((row) => row.startsWith('active_company_id=')) + ?.split('=')[1]; + if (!cookie) return null; + const parsed = Number(cookie); + return Number.isFinite(parsed) ? parsed : null; + } + + function handleSearch() { + if (!browser) return; + clearTimeout(timeout); + timeout = setTimeout(async () => { + loading = true; + try { + const companyId = getActiveCompanyId(); + if (!companyId) { + error = 'No hay empresa activa seleccionada'; + return; + } + const response = await sectorsApi.list(1, pageSize, companyId, searchQuery); + if (!response.error && response.data) { + allItems = response.data.items; + currentPage = 1; + totalItems = response.data.total; + } + } catch (e) { + console.error('Error aplicando filtros:', e); + } finally { + loading = false; + } + const url = new URL($page.url); + if (searchQuery) url.searchParams.set('search', searchQuery); + else url.searchParams.delete('search'); + history.replaceState(history.state, '', url); + }, 500); + } + async function loadMore() { if (loading || !hasMore) return; - loading = true; error = null; - - try { - const companyId = companyStore.activeCompany?.id; - if (!companyId) { - error = 'No hay empresa activa seleccionada'; - return; - } - const response = await sectorsApi.list(currentPage + 1, pageSize, companyId); - + try { + const companyId = getActiveCompanyId(); + if (!companyId) { + error = 'No hay empresa activa seleccionada'; + return; + } + const response = await sectorsApi.list(currentPage + 1, pageSize, companyId, searchQuery); if (response.error) { - console.error('📊 [Page] Error en loadMore:', response.error, 'Status:', response.status); - - // Si es un error de autenticación (401 o 403) y no se pudo refrescar, mostrar mensaje específico if (response.status === 401 || response.status === 403) { error = 'Sesión expirada. Recargando página...'; - // Recargar automáticamente después de 2 segundos - setTimeout(() => { - window.location.reload(); - }, 2000); + setTimeout(() => window.location.reload(), 2000); } else { error = response.error; } return; } - - if (response.data?.items) { - // Agregar los nuevos items al array existente + if (response.data?.items) { allItems = [...allItems, ...response.data.items]; currentPage++; totalItems = response.data.total; } } catch (e) { error = 'Error cargando más datos'; - console.error('📊 [Page] Error loading more:', e); } finally { loading = false; } } function reloadData() { - // Reset y recargar desde el principio window.location.reload(); } - function handleCreateClick() { - showCreateDialog = true; - } - function handleSuccess() { - // Recargar datos después de crear/editar/eliminar reloadData(); } - // Crear columnas con el callback onSuccess + useShortcuts('Sectores', [ + { key: 'Alt+Shift+R', description: 'Actualizar Lista', action: reloadData } + ]); + const columns = createColumns(handleSuccess); -
- -
-
-

Sectores

+
+ +
+
+

+ Sectores +

- Gestiona los sectores económicos + Gestiona los sectores económicos del sistema

- +
+ +
+
+ + +
+
+ Búsqueda por Clave + +
- {#if error} - - - Error - {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 bae3c744..fabc9948 100644 --- a/frontend/src/routes/dashboard/reference_data/states/+page.svelte +++ b/frontend/src/routes/dashboard/reference_data/states/+page.svelte @@ -3,29 +3,25 @@ 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 CreateEditDialog from '$lib/components/dashboard/reference_data/states/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 type { PageData } from './$types'; import { useShortcuts } from '$lib/hooks/use-shortcuts'; - import { obtenerAtajosLista } from '$lib/config/shortcuts/dashboard/reference_data/states/list'; import { browser } from '$app/environment'; - import { Plus, RefreshCw } from 'lucide-svelte'; + import { page } from '$app/stores'; + import { RefreshCw } from 'lucide-svelte'; // Los datos iniciales vienen del servidor let { data }: { data: PageData } = $props(); - - // Estado para el diálogo de crear - let showCreateDialog = $state(false); - // Atajos - useShortcuts( - 'Lista Estados', - obtenerAtajosLista({ - manejarNuevo: () => (showCreateDialog = true), - manejarActualizar: reloadData - }) - ); + // Keyboard Shortcuts + useShortcuts('Estados', [ + { + key: 'Alt+Shift+R', + description: 'Actualizar Lista', + action: reloadData + } + ]); // Sincronizar token de cookies a localStorage al montar el componente onMount(() => { @@ -65,6 +61,34 @@ let hasMore = $derived(allItems.length < totalItems); let error = $state(data.error || null); + // Filtros + let searchQuery = $state($page.url.searchParams.get('search') || ''); + let timeout: ReturnType; + + function handleSearch() { + if (!browser) return; + clearTimeout(timeout); + timeout = setTimeout(async () => { + loading = true; + try { + const response = await statesApi.list(1, pageSize, searchQuery); + if (!response.error && response.data) { + allItems = response.data.items; + currentPage = 1; + totalItems = response.data.total; + } + } catch (e) { + console.error('Error aplicando filtros:', e); + } finally { + loading = false; + } + const url = new URL($page.url); + if (searchQuery) url.searchParams.set('search', searchQuery); + else url.searchParams.delete('search'); + history.replaceState(history.state, '', url); + }, 500); + } + async function loadMore() { if (loading || !hasMore) return; @@ -72,7 +96,7 @@ error = null; try { - const response = await statesApi.list(currentPage + 1, pageSize); + const response = await statesApi.list(currentPage + 1, pageSize, searchQuery); if (response.error) { console.error('📊 [Page] Error en loadMore:', response.error, 'Status:', response.status); @@ -109,10 +133,6 @@ window.location.reload(); } - function handleCreateClick() { - showCreateDialog = true; - } - function handleSuccess() { // Recargar datos después de crear/editar/eliminar reloadData(); @@ -122,59 +142,52 @@ const columns = createColumns(handleSuccess); -
- -
-
-

Estados

+
+ +
+
+

+ Estados +

Gestiona los estados y sus claves de identificación

- +
+ +
+
+ + +
+
+ Búsqueda General + +
- {#if error} - - - Error - {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 511ac0e4..b0574e29 100644 --- a/frontend/src/routes/dashboard/reference_data/transport_modes/+page.svelte +++ b/frontend/src/routes/dashboard/reference_data/transport_modes/+page.svelte @@ -3,56 +3,29 @@ 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 CreateEditDialog from '$lib/components/dashboard/reference_data/transport_modes/create-edit-dialog.svelte'; - import * as Card from '$lib/components/ui/card'; import { Button } from '$lib/components/ui/button'; - import type { PageData } from './$types'; - import { useShortcuts } from '$lib/hooks/use-shortcuts'; - import { obtenerAtajosLista } from '$lib/config/shortcuts/dashboard/reference_data/transport_modes/list'; + import { Input } from '$lib/components/ui/input'; + import { page } from '$app/stores'; import { browser } from '$app/environment'; - import { Plus, RefreshCw } from 'lucide-svelte'; + import { RefreshCw } from 'lucide-svelte'; + import { useShortcuts } from '$lib/hooks/use-shortcuts'; + import type { PageData } from './$types'; // Los datos iniciales vienen del servidor let { data }: { data: PageData } = $props(); - - // Estado para el diálogo de crear - let showCreateDialog = $state(false); - // Atajos - useShortcuts( - 'Lista Modos de Transporte', - obtenerAtajosLista({ - manejarNuevo: () => (showCreateDialog = true), - manejarActualizar: reloadData - }) - ); - - // Sincronizar token de cookies a localStorage al montar el componente + // Sincronizar token de cookies onMount(() => { if (browser) { - // Función para obtener el valor de una cookie const getCookie = (name: string): string | null => { const value = `; ${document.cookie}`; const parts = value.split(`; ${name}=`); if (parts.length === 2) return parts.pop()?.split(';').shift() || null; return null; }; - - // Verificar si hay token en las cookies const cookieToken = getCookie('access_token'); const localToken = localStorage.getItem('access_token'); - - if (cookieToken && cookieToken !== localToken) { - localStorage.setItem('access_token', cookieToken); - } - - // También sincronizar refresh_token si existe - const cookieRefreshToken = getCookie('refresh_token'); - const localRefreshToken = localStorage.getItem('refresh_token'); - - if (cookieRefreshToken && cookieRefreshToken !== localRefreshToken) { - localStorage.setItem('refresh_token', cookieRefreshToken); - } + if (cookieToken && cookieToken !== localToken) localStorage.setItem('access_token', cookieToken); } }); @@ -65,116 +38,116 @@ let hasMore = $derived(allItems.length < totalItems); let error = $state(data.error || null); + // Filtros + let searchQuery = $state($page.url.searchParams.get('search') || ''); + let timeout: ReturnType; + + function handleSearch() { + if (!browser) return; + clearTimeout(timeout); + timeout = setTimeout(async () => { + loading = true; + try { + const response = await transportModesApi.list(1, pageSize, searchQuery); + if (!response.error && response.data) { + allItems = response.data.items; + currentPage = 1; + totalItems = response.data.total; + } + } catch (e) { + console.error('Error aplicando filtros:', e); + } finally { + loading = false; + } + const url = new URL($page.url); + if (searchQuery) url.searchParams.set('search', searchQuery); + else url.searchParams.delete('search'); + history.replaceState(history.state, '', url); + }, 500); + } + async function loadMore() { if (loading || !hasMore) return; - loading = true; error = null; - - try { - const response = await transportModesApi.list(currentPage + 1, pageSize); - + try { + const response = await transportModesApi.list(currentPage + 1, pageSize, searchQuery); if (response.error) { - console.error('📊 [Page] Error en loadMore:', response.error, 'Status:', response.status); - - // Si es un error de autenticación (401 o 403) y no se pudo refrescar, mostrar mensaje específico if (response.status === 401 || response.status === 403) { error = 'Sesión expirada. Recargando página...'; - // Recargar automáticamente después de 2 segundos - setTimeout(() => { - window.location.reload(); - }, 2000); + setTimeout(() => window.location.reload(), 2000); } else { error = response.error; } return; } - - if (response.data?.items) { - // Agregar los nuevos items al array existente + if (response.data?.items) { allItems = [...allItems, ...response.data.items]; currentPage++; totalItems = response.data.total; } } catch (e) { error = 'Error cargando más datos'; - console.error('📊 [Page] Error loading more:', e); } finally { loading = false; } } function reloadData() { - // Reset y recargar desde el principio window.location.reload(); } - function handleCreateClick() { - showCreateDialog = true; - } - function handleSuccess() { - // Recargar datos después de crear/editar/eliminar reloadData(); } - // Crear columnas con el callback onSuccess + useShortcuts('Modos de Transporte', [ + { key: 'Alt+Shift+R', description: 'Actualizar Lista', action: reloadData } + ]); + const columns = createColumns(handleSuccess); -
- -
-
-

Modos de Transporte

+
+ +
+
+

+ Modos de Transporte +

- Gestiona los modos de transporte disponibles + Gestiona los modos de transporte disponibles en el sistema

- +
+ +
+
+ + +
+
+ Búsqueda General + +
- {#if error} - - - Error - {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 6506fd52..5247408a 100644 --- a/frontend/src/routes/dashboard/reference_data/transport_types/+page.svelte +++ b/frontend/src/routes/dashboard/reference_data/transport_types/+page.svelte @@ -3,56 +3,29 @@ 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 CreateEditDialog from '$lib/components/dashboard/reference_data/transport_types/create-edit-dialog.svelte'; - import * as Card from '$lib/components/ui/card'; import { Button } from '$lib/components/ui/button'; - import { Plus, RefreshCw } from 'lucide-svelte'; - import type { PageData } from './$types'; - import { useShortcuts } from '$lib/hooks/use-shortcuts'; - import { obtenerAtajosLista } from '$lib/config/shortcuts/dashboard/reference_data/transport_types/list'; + import { Input } from '$lib/components/ui/input'; + import { page } from '$app/stores'; import { browser } from '$app/environment'; + import { RefreshCw } from 'lucide-svelte'; + import { useShortcuts } from '$lib/hooks/use-shortcuts'; + import type { PageData } from './$types'; // Los datos iniciales vienen del servidor let { data }: { data: PageData } = $props(); - - // Estado para el diálogo de crear - let showCreateDialog = $state(false); - // Atajos - useShortcuts( - 'Lista Tipos de Transporte', - obtenerAtajosLista({ - manejarNuevo: () => (showCreateDialog = true), - manejarActualizar: reloadData - }) - ); - - // Sincronizar token de cookies a localStorage al montar el componente + // Sincronizar token de cookies onMount(() => { if (browser) { - // Función para obtener el valor de una cookie const getCookie = (name: string): string | null => { const value = `; ${document.cookie}`; const parts = value.split(`; ${name}=`); if (parts.length === 2) return parts.pop()?.split(';').shift() || null; return null; }; - - // Verificar si hay token en las cookies const cookieToken = getCookie('access_token'); const localToken = localStorage.getItem('access_token'); - - if (cookieToken && cookieToken !== localToken) { - localStorage.setItem('access_token', cookieToken); - } - - // También sincronizar refresh_token si existe - const cookieRefreshToken = getCookie('refresh_token'); - const localRefreshToken = localStorage.getItem('refresh_token'); - - if (cookieRefreshToken && cookieRefreshToken !== localRefreshToken) { - localStorage.setItem('refresh_token', cookieRefreshToken); - } + if (cookieToken && cookieToken !== localToken) localStorage.setItem('access_token', cookieToken); } }); @@ -65,116 +38,116 @@ let hasMore = $derived(allItems.length < totalItems); let error = $state(data.error || null); + // Filtros + let searchQuery = $state($page.url.searchParams.get('search') || ''); + let timeout: ReturnType; + + function handleSearch() { + if (!browser) return; + clearTimeout(timeout); + timeout = setTimeout(async () => { + loading = true; + try { + const response = await transportTypesApi.list(1, pageSize, searchQuery); + if (!response.error && response.data) { + allItems = response.data.items; + currentPage = 1; + totalItems = response.data.total; + } + } catch (e) { + console.error('Error aplicando filtros:', e); + } finally { + loading = false; + } + const url = new URL($page.url); + if (searchQuery) url.searchParams.set('search', searchQuery); + else url.searchParams.delete('search'); + history.replaceState(history.state, '', url); + }, 500); + } + async function loadMore() { if (loading || !hasMore) return; - loading = true; error = null; - - try { - const response = await transportTypesApi.list(currentPage + 1, pageSize); - + try { + const response = await transportTypesApi.list(currentPage + 1, pageSize, searchQuery); if (response.error) { - console.error('📊 [Page] Error en loadMore:', response.error, 'Status:', response.status); - - // Si es un error de autenticación (401 o 403) y no se pudo refrescar, mostrar mensaje específico if (response.status === 401 || response.status === 403) { error = 'Sesión expirada. Recargando página...'; - // Recargar automáticamente después de 2 segundos - setTimeout(() => { - window.location.reload(); - }, 2000); + setTimeout(() => window.location.reload(), 2000); } else { error = response.error; } return; } - - if (response.data?.items) { - // Agregar los nuevos items al array existente + if (response.data?.items) { allItems = [...allItems, ...response.data.items]; currentPage++; totalItems = response.data.total; } } catch (e) { error = 'Error cargando más datos'; - console.error('📊 [Page] Error loading more:', e); } finally { loading = false; } } function reloadData() { - // Reset y recargar desde el principio window.location.reload(); } - function handleCreateClick() { - showCreateDialog = true; - } - function handleSuccess() { - // Recargar datos después de crear/editar/eliminar reloadData(); } - // Crear columnas con el callback onSuccess + useShortcuts('Tipos de Transporte', [ + { key: 'Alt+Shift+R', description: 'Actualizar Lista', action: reloadData } + ]); + const columns = createColumns(handleSuccess); -
- -
-
-

Tipos de Transporte

+
+ +
+
+

+ Tipos de Transporte +

Gestiona los tipos de transporte según código SAT

- +
+ +
+
+ + +
+
+ Búsqueda General + +
- {#if error} - - - Error - {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 59c8a0fc..c58c4ec2 100644 --- a/frontend/src/routes/dashboard/reference_data/valuation_methods/+page.svelte +++ b/frontend/src/routes/dashboard/reference_data/valuation_methods/+page.svelte @@ -3,55 +3,29 @@ 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 CreateEditDialog from '$lib/components/dashboard/reference_data/valuation_methods/create-edit-dialog.svelte'; import { Button } from '$lib/components/ui/button'; - import { Plus, RefreshCw } from 'lucide-svelte'; - import { useShortcuts } from '$lib/hooks/use-shortcuts'; - import { obtenerAtajosLista } from '$lib/config/shortcuts/dashboard/reference_data/valuation_methods/list'; - import type { PageData } from './$types'; + import { Input } from '$lib/components/ui/input'; + import { page } from '$app/stores'; import { browser } from '$app/environment'; + import { RefreshCw } from 'lucide-svelte'; + import { useShortcuts } from '$lib/hooks/use-shortcuts'; + import type { PageData } from './$types'; // Los datos iniciales vienen del servidor let { data }: { data: PageData } = $props(); - - // Estado para el diálogo de crear - let showCreateDialog = $state(false); - // Atajos - useShortcuts( - 'Lista Métodos de Valoración', - obtenerAtajosLista({ - manejarNuevo: () => (showCreateDialog = true), - manejarActualizar: reloadData - }) - ); - - // Sincronizar token de cookies a localStorage al montar el componente + // Sincronizar token de cookies onMount(() => { if (browser) { - // Función para obtener el valor de una cookie const getCookie = (name: string): string | null => { const value = `; ${document.cookie}`; const parts = value.split(`; ${name}=`); if (parts.length === 2) return parts.pop()?.split(';').shift() || null; return null; }; - - // Verificar si hay token en las cookies const cookieToken = getCookie('access_token'); const localToken = localStorage.getItem('access_token'); - - if (cookieToken && cookieToken !== localToken) { - localStorage.setItem('access_token', cookieToken); - } - - // También sincronizar refresh_token si existe - const cookieRefreshToken = getCookie('refresh_token'); - const localRefreshToken = localStorage.getItem('refresh_token'); - - if (cookieRefreshToken && cookieRefreshToken !== localRefreshToken) { - localStorage.setItem('refresh_token', cookieRefreshToken); - } + if (cookieToken && cookieToken !== localToken) localStorage.setItem('access_token', cookieToken); } }); @@ -64,98 +38,116 @@ let hasMore = $derived(allItems.length < totalItems); let error = $state(data.error || null); + // Filtros + let searchQuery = $state($page.url.searchParams.get('search') || ''); + let timeout: ReturnType; + + function handleSearch() { + if (!browser) return; + clearTimeout(timeout); + timeout = setTimeout(async () => { + loading = true; + try { + const response = await valuationMethodsApi.list(1, pageSize, searchQuery); + if (!response.error && response.data) { + allItems = response.data.items; + currentPage = 1; + totalItems = response.data.total; + } + } catch (e) { + console.error('Error aplicando filtros:', e); + } finally { + loading = false; + } + const url = new URL($page.url); + if (searchQuery) url.searchParams.set('search', searchQuery); + else url.searchParams.delete('search'); + history.replaceState(history.state, '', url); + }, 500); + } + async function loadMore() { if (loading || !hasMore) return; - loading = true; error = null; - - try { - const response = await valuationMethodsApi.list(currentPage + 1, pageSize); - + try { + const response = await valuationMethodsApi.list(currentPage + 1, pageSize, searchQuery); if (response.error) { - console.error('📊 [Page] Error en loadMore:', response.error, 'Status:', response.status); - - // Si es un error de autenticación (401 o 403) y no se pudo refrescar, mostrar mensaje específico if (response.status === 401 || response.status === 403) { error = 'Sesión expirada. Recargando página...'; - // Recargar automáticamente después de 2 segundos - setTimeout(() => { - window.location.reload(); - }, 2000); + setTimeout(() => window.location.reload(), 2000); } else { error = response.error; } return; } - - if (response.data?.items) { - // Agregar los nuevos items al array existente + if (response.data?.items) { allItems = [...allItems, ...response.data.items]; currentPage++; totalItems = response.data.total; } } catch (e) { error = 'Error cargando más datos'; - console.error('📊 [Page] Error loading more:', e); } finally { loading = false; } } function reloadData() { - // Reset y recargar desde el principio window.location.reload(); } - function handleCreateClick() { - showCreateDialog = true; - } - function handleSuccess() { - // Recargar datos después de crear/editar/eliminar reloadData(); } - // Crear columnas con el callback onSuccess + useShortcuts('Métodos de Valoración', [ + { key: 'Alt+Shift+R', description: 'Actualizar Lista', action: reloadData } + ]); + const columns = createColumns(handleSuccess); -
-
-
-

Métodos de Valoración

+
+ +
+
+

+ Métodos de Valoración +

- Gestiona los métodos de valoración aduanera + Gestiona los métodos de valoración aduanera autorizados

-
- - +
+
+ + +
+
+ Búsqueda General +
{#if error} -
+
{error}
{/if} -
- + +
+
- -