fix/secciones-aduanales-en-custom-brokers (#484)
ajuste en pestana de custom brokers de secciones aduanales, correcciones visuales y consulta de datos Reviewed-on: ADUANASOFT/anexo76#484 Co-authored-by: hreyes <hreyes@aduanasoft.com.mx> Co-committed-by: hreyes <hreyes@aduanasoft.com.mx>
This commit is contained in:
@@ -75,10 +75,14 @@
|
||||
const canDeleteBroker = $derived(canDeleteCustomsBrokers($currentUser));
|
||||
|
||||
// --- Customs Sections State ---
|
||||
// Catálogo de solo lectura: se alimenta del mismo endpoint que
|
||||
// /dashboard/reference_data/customs_sections (mismo origen de datos).
|
||||
let sections = $state<CustomsSection[]>([]);
|
||||
let loadingSections = $state(false);
|
||||
let totalSections = $state(0);
|
||||
let sectionsPage = $state(1);
|
||||
let sectionsSearch = $state('');
|
||||
let sectionsSearchTimeout: ReturnType<typeof setTimeout>;
|
||||
let hasMoreSections = $derived(sections.length < totalSections);
|
||||
|
||||
// --- Lifecycle ---
|
||||
@@ -160,12 +164,14 @@
|
||||
|
||||
// Customs Sections Actions
|
||||
async function loadSections() {
|
||||
// Simple loading logic reusing existing API
|
||||
// Assuming we load all or paginate - trying to match existing page logic
|
||||
if (loadingSections) return;
|
||||
// El store puede no estar hidratado al montar (su init corre en el onMount
|
||||
// del layout padre); usamos el companyId resuelto por SSR como respaldo.
|
||||
const companyId = companyStore.activeCompany?.id ?? data.currentCompanyId;
|
||||
if (!companyId) return;
|
||||
loadingSections = true;
|
||||
try {
|
||||
const response = await customsSectionsApi.list(sectionsPage, 50);
|
||||
const response = await customsSectionsApi.list(companyId, sectionsPage, 50, sectionsSearch);
|
||||
if (response.data?.items) {
|
||||
sections = sectionsPage === 1 ? response.data.items : [...sections, ...response.data.items];
|
||||
totalSections = response.data.total;
|
||||
@@ -183,6 +189,15 @@
|
||||
await loadSections();
|
||||
}
|
||||
|
||||
// Búsqueda server-side con debounce; resetea a la primera página
|
||||
function handleSectionsSearch() {
|
||||
clearTimeout(sectionsSearchTimeout);
|
||||
sectionsSearchTimeout = setTimeout(() => {
|
||||
sectionsPage = 1;
|
||||
loadSections();
|
||||
}, 500);
|
||||
}
|
||||
|
||||
// Shortcuts Integration
|
||||
useShortcuts(
|
||||
'Customs Brokers List',
|
||||
@@ -196,11 +211,8 @@
|
||||
return;
|
||||
}
|
||||
goto('/dashboard/customs_brokers/edit/new');
|
||||
} else {
|
||||
// For Customs Sections, we might need a dialog.
|
||||
// Since we are "not modifying logic", we'll just show a toast or Placeholder TODO
|
||||
toast.info('Crear Sección Aduanal: Implementación pendiente de diálogo');
|
||||
}
|
||||
// Secciones Aduanales es un catálogo de solo lectura: sin acción de crear.
|
||||
},
|
||||
recargar: () => {
|
||||
if (activeTab === 'brokers') loadItems();
|
||||
@@ -212,10 +224,14 @@
|
||||
})
|
||||
);
|
||||
|
||||
const sectionsColumns = createSectionColumns(() => {
|
||||
sectionsPage = 1;
|
||||
loadSections();
|
||||
});
|
||||
// Solo lectura: se ocultan las acciones de Editar/Eliminar en el menú de cada fila.
|
||||
const sectionsColumns = createSectionColumns(
|
||||
() => {
|
||||
sectionsPage = 1;
|
||||
loadSections();
|
||||
},
|
||||
{ canEdit: false, canDelete: false }
|
||||
);
|
||||
|
||||
const brokerColumns = createBrokerColumns(handleActionSuccess);
|
||||
</script>
|
||||
@@ -432,18 +448,37 @@
|
||||
</div>
|
||||
</Tabs.Content>
|
||||
|
||||
<Tabs.Content value="customs" class="mt-0 flex-1 overflow-auto data-[state=inactive]:hidden">
|
||||
<Card.Root class="flex h-full flex-col border-none shadow-none">
|
||||
<Card.Content class="flex-1 p-0">
|
||||
<SectionsDataTable
|
||||
data={sections}
|
||||
columns={sectionsColumns}
|
||||
loading={loadingSections}
|
||||
hasMore={hasMoreSections}
|
||||
loadMore={loadMoreSections}
|
||||
/>
|
||||
<Tabs.Content
|
||||
value="customs"
|
||||
class="mt-0 flex min-h-0 flex-1 flex-col overflow-hidden data-[state=inactive]:hidden"
|
||||
>
|
||||
<Card.Root class="flex min-h-0 flex-1 flex-col overflow-hidden border bg-background">
|
||||
<Card.Header>
|
||||
<div class="flex flex-wrap items-center justify-between gap-3">
|
||||
<Card.Title>Listado de Secciones Aduanales</Card.Title>
|
||||
<Input
|
||||
placeholder="Buscar"
|
||||
bind:value={sectionsSearch}
|
||||
oninput={handleSectionsSearch}
|
||||
class="h-9 w-44 bg-card lg:w-64"
|
||||
/>
|
||||
</div>
|
||||
</Card.Header>
|
||||
<Card.Content class="flex min-h-0 flex-1 flex-col overflow-hidden p-0">
|
||||
<div class="h-full flex-1 overflow-hidden rounded-md border bg-background">
|
||||
<SectionsDataTable
|
||||
data={sections}
|
||||
columns={sectionsColumns}
|
||||
loading={loadingSections}
|
||||
hasMore={hasMoreSections}
|
||||
loadMore={loadMoreSections}
|
||||
/>
|
||||
</div>
|
||||
</Card.Content>
|
||||
</Card.Root>
|
||||
<div class="flex-none px-1 pt-3 text-sm text-muted-foreground">
|
||||
Mostrando {sections.length} de {totalSections} registros
|
||||
</div>
|
||||
</Tabs.Content>
|
||||
</Tabs.Root>
|
||||
|
||||
@@ -482,12 +517,8 @@
|
||||
Borrar
|
||||
</Button>
|
||||
{/if}
|
||||
{:else}
|
||||
<Button size="sm" onclick={() => toast.info('Pendiente')}>
|
||||
<Plus class="mr-1 h-4 w-4" />
|
||||
Nueva Sección
|
||||
</Button>
|
||||
{/if}
|
||||
<!-- Secciones Aduanales es solo lectura: sin botón de creación. -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user