checkpoint/backup-fail-server

This commit is contained in:
hreyes
2026-02-05 12:35:03 -06:00
parent 8e53293e62
commit 4cc613d1df
7 changed files with 234 additions and 75 deletions

View File

@@ -32,7 +32,7 @@ export function createColumns(onSuccess?: () => void): ColumnDef<Doda>[] {
},
{
id: 'actions',
Headers: 'Acciones',
header: 'Acciones',
cell: ({ row }) => {
return renderComponent(DataTableActions, {
item: row.original,

View File

@@ -0,0 +1,121 @@
<script lang="ts" generics="TData, TValue">
import { type ColumnDef, getCoreRowModel, type RowSelectionState } from '@tanstack/table-core';
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<TData, TValue> = {
columns: ColumnDef<TData, TValue>[];
data: TData[];
pageCount: number;
totalItems: number;
selectedId?: number | null;
onRowClick?: (row: TData) => void;
};
let {
data,
columns,
pageCount,
totalItems,
selectedId = null,
onRowClick
}: DataTableProps<TData, TValue> = $props();
const table = createSvelteTable({
get data() {
return data;
},
columns,
getCoreRowModel: getCoreRowModel(),
getRowId: (row: any) => row.id?.toString(),
state: {
get rowSelection() {
return selectedId ? { [selectedId]: true } : {};
}
},
enableRowSelection: true,
enableMultiRowSelection: false,
manualPagination: true,
pageCount: pageCount
});
function handlePageChange(newPage: number) {
const url = new URL($page.url);
url.searchParams.set('page', newPage.toString());
goto(url);
}
</script>
<div class="space-y-4">
<div class="rounded-md border">
<Table.Root>
<Table.Header>
{#each table.getHeaderGroups() as headerGroup (headerGroup.id)}
<Table.Row>
{#each headerGroup.headers as header (header.id)}
<Table.Head class="whitespace-nowrap">
{#if !header.isPlaceholder}
<FlexRender
content={header.column.columnDef.header}
context={header.getContext()}
/>
{/if}
</Table.Head>
{/each}
</Table.Row>
{/each}
</Table.Header>
<Table.Body>
{#each table.getRowModel().rows as row (row.id)}
<Table.Row
data-state={row.getIsSelected() && 'selected'}
onclick={() => onRowClick?.(row.original)}
class="cursor-pointer hover:bg-muted/50 transition-colors {row.getIsSelected()
? 'bg-primary/10'
: ''}"
>
{#each row.getVisibleCells() as cell (cell.id)}
<Table.Cell class="whitespace-nowrap">
<FlexRender content={cell.column.columnDef.cell} context={cell.getContext()} />
</Table.Cell>
{/each}
</Table.Row>
{:else}
<Table.Row>
<Table.Cell colspan={columns.length} class="h-24 text-center">
No hay resultados.
</Table.Cell>
</Table.Row>
{/each}
</Table.Body>
</Table.Root>
</div>
<!-- Paginación -->
<div class="flex items-center justify-end space-x-2 py-4">
<div class="flex-1 text-sm text-muted-foreground">
Total: {totalItems}
</div>
<div class="space-x-2">
<Button
variant="outline"
size="sm"
onclick={() => handlePageChange(Number($page.url.searchParams.get('page') || 1) - 1)}
disabled={Number($page.url.searchParams.get('page') || 1) <= 1}
>
Anterior
</Button>
<Button
variant="outline"
size="sm"
onclick={() => handlePageChange(Number($page.url.searchParams.get('page') || 1) + 1)}
disabled={Number($page.url.searchParams.get('page') || 1) >= pageCount}
>
Siguiente
</Button>
</div>
</div>
</div>

View File

@@ -25,9 +25,12 @@
'input:not([disabled]):not([type="hidden"]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]):not([role="tab"])'
);
// Find the first one that is actually visible
// Find the first one that is actually visible AND not in the sidebar
const firstVisible = Array.from(focusables).find((el) => {
const htmlEl = el as HTMLElement;
// Exclude sidebar elements
if (htmlEl.closest('[data-sidebar="sidebar"]')) return false;
return !!(htmlEl.offsetWidth || htmlEl.offsetHeight || htmlEl.getClientRects().length);
}) as HTMLElement;
@@ -60,6 +63,9 @@
const elements = document.querySelectorAll('button, [role="tab"], a');
const target = Array.from(elements).find((el) => {
const text = el.textContent?.trim() || '';
// Exclude sidebar
if (el.closest('[data-sidebar="sidebar"]')) return false;
return text.toLowerCase().includes(keyword.toLowerCase());
}) as HTMLElement;
@@ -276,6 +282,9 @@
const target = event.target as HTMLElement;
if (!target) return;
// Exclude sidebar from any magic scrolling
if (target.closest('[data-sidebar="sidebar"]')) return;
// Check if it's an interactive element we care about
const isInteractive =
['INPUT', 'TEXTAREA', 'SELECT', 'BUTTON', 'A'].includes(target.tagName) ||