- Added create-edit-dialog component for creating and editing pedimentos. - Integrated dialog with data table actions for editing existing pedimentos. - Implemented infinite scroll functionality in the data table for loading more pedimentos. - Enhanced server-side loading of pedimentos with authentication checks. - Added filtering options for pedimentos based on status, client ID, and year. - Improved error handling and user feedback for actions like creating, editing, and deleting pedimentos.
180 lines
4.3 KiB
Svelte
180 lines
4.3 KiB
Svelte
<script lang="ts">
|
|
import { Button } from "$lib/components/ui/button";
|
|
import * as DropdownMenu from "$lib/components/ui/dropdown-menu";
|
|
import { pedimentosApi, type Pedimento } from "$lib/api/dashboard/a76/pedimentos";
|
|
|
|
let {
|
|
item,
|
|
onSuccess
|
|
}: {
|
|
item: Pedimento;
|
|
onSuccess?: () => void;
|
|
} = $props();
|
|
|
|
let showEditDialog = $state(false);
|
|
let showDeleteDialog = $state(false);
|
|
let loading = $state(false);
|
|
let error = $state<string | null>(null);
|
|
|
|
async function handleDelete() {
|
|
if (!confirm(`¿Estás seguro de eliminar el pedimento #${item.id}?`)) {
|
|
return;
|
|
}
|
|
|
|
loading = true;
|
|
error = null;
|
|
|
|
try {
|
|
const response = await pedimentosApi.delete(item.id);
|
|
|
|
if (response.error) {
|
|
if (response.status === 401) {
|
|
error = 'Sesión expirada. Recargando página...';
|
|
setTimeout(() => {
|
|
window.location.reload();
|
|
}, 1500);
|
|
} else {
|
|
error = response.error;
|
|
alert(`Error al eliminar: ${response.error}`);
|
|
}
|
|
return;
|
|
}
|
|
|
|
// Éxito
|
|
if (onSuccess) {
|
|
onSuccess();
|
|
}
|
|
} catch (e) {
|
|
error = e instanceof Error ? e.message : "Error al eliminar";
|
|
alert(`Error: ${error}`);
|
|
console.error("Error deleting:", e);
|
|
} finally {
|
|
loading = false;
|
|
}
|
|
}
|
|
|
|
function handleEdit() {
|
|
showEditDialog = true;
|
|
}
|
|
|
|
function handleView() {
|
|
// Navegar a la vista de detalles
|
|
window.location.href = `/dashboard/pedimentos/${item.id}`;
|
|
}
|
|
</script>
|
|
|
|
<DropdownMenu.Root>
|
|
<DropdownMenu.Trigger>
|
|
{#snippet child({ props })}
|
|
<Button {...props} variant="ghost" size="icon" class="relative size-8 p-0">
|
|
<span class="sr-only">Abrir menú</span>
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
width="16"
|
|
height="16"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
>
|
|
<circle cx="12" cy="12" r="1" />
|
|
<circle cx="12" cy="5" r="1" />
|
|
<circle cx="12" cy="19" r="1" />
|
|
</svg>
|
|
</Button>
|
|
{/snippet}
|
|
</DropdownMenu.Trigger>
|
|
<DropdownMenu.Content align="end" class="w-[160px]">
|
|
<DropdownMenu.Label>Acciones</DropdownMenu.Label>
|
|
<DropdownMenu.Separator />
|
|
<DropdownMenu.Item onclick={handleView}>
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
width="16"
|
|
height="16"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
class="mr-2"
|
|
>
|
|
<path d="M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7Z" />
|
|
<circle cx="12" cy="12" r="3" />
|
|
</svg>
|
|
Ver detalles
|
|
</DropdownMenu.Item>
|
|
<DropdownMenu.Item onclick={handleEdit}>
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
width="16"
|
|
height="16"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
class="mr-2"
|
|
>
|
|
<path d="M17 3a2.85 2.83 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5Z" />
|
|
<path d="m15 5 4 4" />
|
|
</svg>
|
|
Editar
|
|
</DropdownMenu.Item>
|
|
<DropdownMenu.Separator />
|
|
<DropdownMenu.Item onclick={handleDelete} class="text-destructive" disabled={loading}>
|
|
{#if loading}
|
|
<svg
|
|
class="mr-2 h-4 w-4 animate-spin"
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
fill="none"
|
|
viewBox="0 0 24 24"
|
|
>
|
|
<circle
|
|
class="opacity-25"
|
|
cx="12"
|
|
cy="12"
|
|
r="10"
|
|
stroke="currentColor"
|
|
stroke-width="4"
|
|
></circle>
|
|
<path
|
|
class="opacity-75"
|
|
fill="currentColor"
|
|
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
|
|
></path>
|
|
</svg>
|
|
{:else}
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
width="16"
|
|
height="16"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
class="mr-2"
|
|
>
|
|
<path d="M3 6h18" />
|
|
<path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6" />
|
|
<path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2" />
|
|
</svg>
|
|
{/if}
|
|
Eliminar
|
|
</DropdownMenu.Item>
|
|
</DropdownMenu.Content>
|
|
</DropdownMenu.Root>
|
|
|
|
{#if showEditDialog}
|
|
<!-- Importar dinámicamente el componente de edición cuando se necesite -->
|
|
{#await import('./create-edit-dialog.svelte') then { default: CreateEditDialog }}
|
|
<CreateEditDialog bind:open={showEditDialog} bind:item onSuccess={onSuccess} />
|
|
{/await}
|
|
{/if}
|