Limpieza y correcion de warnings en ultimos cambios

This commit is contained in:
2026-03-27 09:15:58 -05:00
parent d93c4c6b7b
commit dd4eec56f8
6 changed files with 121 additions and 111 deletions

View File

@@ -34,7 +34,7 @@ export function createColumns(onSuccess?: () => void): ColumnDef<Part>[] {
// Usamos el componente Checkbox si es posible, pero para snippets crudos en TanStack 5
// a veces es más directo un input o un Snippet de Svelte.
// Aquí usaremos renderComponent para el Checkbox real.
return "";
return "<span></span>";
}
};
});
@@ -162,9 +162,7 @@ export function createColumns(onSuccess?: () => void): ColumnDef<Part>[] {
const { um } = getUm();
return {
render: () =>
`<span class="inline-flex items-center rounded-sm bg-blue-50 dark:bg-blue-900 text-blue-700 dark:text-blue-300 px-1.5 py-0.5 text-[10px] font-bold ring-1 ring-inset ring-blue-700/10">
${um || '-'}
</span>`
`<span class="inline-flex items-center rounded-sm bg-blue-50 dark:bg-blue-900 text-blue-700 dark:text-blue-300 px-1.5 py-0.5 text-[10px] font-bold ring-1 ring-inset ring-blue-700/10">${um || '-'}</span>`
};
});
return renderSnippet(umSnippet, { um: row.original.unit_of_measure });
@@ -246,7 +244,7 @@ export function createColumns(onSuccess?: () => void): ColumnDef<Part>[] {
const { weight, type } = getWeight();
return {
render: () => {
if (weight === null || weight === undefined) return '-';
if (weight === null || weight === undefined) return '<span>-</span>';
return `<div class="text-xs font-mono">${Number(weight).toFixed(4)} ${type || ''}</div>`;
}
};
@@ -281,7 +279,7 @@ export function createColumns(onSuccess?: () => void): ColumnDef<Part>[] {
cell: ({ row }) => {
const dateSnippet = createRawSnippet<[{ date: string }]>((getDate) => {
const { date } = getDate();
if (!date) return { render: () => '-' };
if (!date) return { render: () => '<span>-</span>' };
const formatted = new Date(date).toLocaleDateString('es-MX', {
year: 'numeric',
month: '2-digit',

View File

@@ -152,9 +152,7 @@ export function createColumns(
const { type, colorClass } = getProps();
return {
render: () =>
`<span class="inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium ${colorClass}">
${type || '-'}
</span>`
`<span class="inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium ${colorClass}">${type || '-'}</span>`
};
});
return renderSnippet(typeSnippet, { type: invoiceType, colorClass });

View File

@@ -53,11 +53,15 @@
},
onStateChange: (updater: any) => {
if (onSortingChange) {
const nextSorting = typeof updater === 'function' ? updater(sorting) : updater;
if (nextSorting.sorting !== undefined) {
onSortingChange(nextSorting.sorting);
} else {
onSortingChange(nextSorting);
const currentState = table.getState();
const nextState = typeof updater === 'function' ? updater(currentState) : updater;
// Identify if this was a sorting update or at least contains sorting
if (nextState && nextState.sorting !== undefined) {
onSortingChange(nextState.sorting);
} else if (Array.isArray(nextState)) {
// Fallback for when updater might return just the array slice
onSortingChange(nextState);
}
}
},

View File

@@ -64,12 +64,14 @@
: null
);
// Ensure descriptions.has_serial has default
$effect(() => {
if (descriptions && descriptions.has_serial === undefined) {
descriptions.has_serial = false;
const internalHasSerial = $derived(descriptions?.has_serial === true);
function toggleHasSerial() {
if (descriptions) {
descriptions.has_serial = !descriptions.has_serial;
}
});
}
const hasSerial = $derived(internalHasSerial);
// Ensure current serie has defaults for form fields
$effect(() => {
@@ -83,7 +85,6 @@
}
});
const hasSerial = $derived(Boolean(descriptions?.has_serial));
const invoiceNumber = $derived(invoice?.invoice_number || '');
const invoiceLine = $derived(lineItem?.line_number != null ? String(lineItem.line_number) : '');
const partNumber = $derived((lineItem as any)?.part_number_display || lineItem?.part_number || '');
@@ -137,7 +138,11 @@
<div class="flex items-center justify-between gap-2 flex-wrap">
<div class="flex items-center space-x-1.5">
<Checkbox id="has_serial" bind:checked={descriptions.has_serial} />
<Checkbox
id="has_serial"
checked={descriptions?.has_serial === true}
onCheckedChange={(v: boolean) => { if (descriptions) descriptions.has_serial = v; }}
/>
<Label for="has_serial" class="text-xs font-normal">Lleva serie (LLEVASERIE)</Label>
</div>
<Button

View File

@@ -6,6 +6,7 @@
import { toast } from 'svelte-sonner';
import { helpApi, type HelpArticle } from '$lib/api/help';
import { helpStore } from '$lib/stores/help.svelte';
import { browser } from '$app/environment';
// Nota: Estas librerías deben ser instaladas: npm install marked dompurify @types/dompurify
// Si no están, fallará el import. El usuario debe instalarlas.
@@ -133,96 +134,100 @@
</Sheet.Trigger>
<Sheet.Content side="right" class="w-[400px] sm:w-[540px]">
<Sheet.Header>
<Sheet.Title class="flex items-center gap-2">
{#if selectedArticle}
<Button variant="ghost" size="icon" onclick={() => (selectedArticle = null)}>
<ChevronLeft size={20} />
</Button>
{/if}
Base de Conocimientos
</Sheet.Title>
</Sheet.Header>
<Sheet.Title class="flex items-center gap-2">
{#if selectedArticle}
<Button variant="ghost" size="icon" onclick={() => (selectedArticle = null)}>
<ChevronLeft size={20} />
</Button>
{/if}
<span>Base de Conocimientos</span>
</Sheet.Title>
</Sheet.Header>
<div class="mt-6 flex h-[calc(100vh-120px)] flex-col">
{#if !selectedArticle}
<div class="space-y-4">
<div class="flex items-center justify-between">
<h3 class="text-lg font-medium">Artículos Disponibles</h3>
{#if isAdmin}
<Button variant="outline" size="sm" onclick={startCreate}>
<Plus size={16} class="mr-2" /> Agregar Nuevo
</Button>
<div class="mt-6 flex h-[calc(100vh-120px)] flex-col">
{#if !selectedArticle}
<div class="space-y-4">
<div class="flex items-center justify-between">
<h3 class="text-lg font-medium">Artículos Disponibles</h3>
{#if isAdmin}
<Button variant="outline" size="sm" onclick={startCreate}>
<Plus size={16} class="mr-2" /> <span>Agregar Nuevo</span>
</Button>
{/if}
</div>
{#if isLoading}
<p class="py-10 text-center text-sm text-muted-foreground">Cargando...</p>
{:else if articles.length === 0}
<p class="py-10 text-center text-sm text-muted-foreground">
No hay artículos de ayuda disponibles.
</p>
{/if}
<div class="grid gap-2">
{#each articles as article (article.uuid)}
<button
onclick={() => selectArticle(article)}
class="flex flex-col items-start rounded-lg border p-4 text-left transition-colors hover:bg-accent"
>
<span class="font-semibold">{article.title}</span>
<span class="text-xs text-muted-foreground">
Última edición: {browser ? new Date(article.updated_at).toLocaleDateString() : article.updated_at.split('T')[0]}
</span>
</button>
{/each}
</div>
</div>
{:else}
<div class="flex flex-1 flex-col gap-4">
{#if isEditing}
<div class="space-y-4">
<input
bind:value={editTitle}
class="w-full rounded-md border bg-transparent p-2 text-xl font-bold"
placeholder="Título del artículo"
/>
<textarea
bind:value={editContent}
class="min-h-[400px] w-full flex-1 rounded-md border bg-transparent p-4 font-mono text-sm focus:ring-1 focus:ring-primary focus:outline-none"
placeholder="Escribe en Markdown..."
></textarea>
<div class="flex justify-end gap-2">
<Button
variant="outline"
onclick={() => {
isEditing = false;
if (isCreating) selectedArticle = null;
isCreating = false;
}}
>
<X size={16} class="mr-2" /> <span>Cancelar</span>
</Button>
<Button onclick={saveChanges}>
<Save size={16} class="mr-2" /> <span>Guardar Cambios</span>
</Button>
</div>
</div>
{:else}
<div class="flex flex-col gap-4">
<div class="flex items-center justify-between">
<h2 class="text-2xl font-bold">{selectedArticle.title}</h2>
{#if isAdmin}
<Button variant="outline" size="sm" onclick={startEdit}>
<Edit2 size={16} class="mr-2" /> <span>Editar</span>
</Button>
{/if}
</div>
<div class="prose prose-sm max-w-none border-t pt-4 dark:prose-invert">
{#if browser}
{@html renderMarkdown(selectedArticle.content)}
{:else}
<div class="whitespace-pre-wrap">{selectedArticle.content}</div>
{/if}
</div>
</div>
{/if}
</div>
{#if isLoading}
<p class="py-10 text-center text-sm text-muted-foreground">Cargando...</p>
{:else if articles.length === 0}
<p class="py-10 text-center text-sm text-muted-foreground">
No hay artículos de ayuda disponibles.
</p>
{/if}
<div class="grid gap-2">
{#each articles as article}
<button
onclick={() => selectArticle(article)}
class="flex flex-col items-start rounded-lg border p-4 text-left transition-colors hover:bg-accent"
>
<span class="font-semibold">{article.title}</span>
<span class="text-xs text-muted-foreground"
>Última edición: {new Date(article.updated_at).toLocaleDateString()}</span
>
</button>
{/each}
</div>
</div>
{:else}
<div class="flex flex-1 flex-col gap-4">
{#if isEditing}
<div class="space-y-4">
<input
bind:value={editTitle}
class="w-full rounded-md border bg-transparent p-2 text-xl font-bold"
placeholder="Título del artículo"
/>
<textarea
bind:value={editContent}
class="min-h-[400px] w-full flex-1 rounded-md border bg-transparent p-4 font-mono text-sm focus:ring-1 focus:ring-primary focus:outline-none"
placeholder="Escribe en Markdown..."
></textarea>
<div class="flex justify-end gap-2">
<Button
variant="outline"
onclick={() => {
isEditing = false;
if (isCreating) selectedArticle = null;
isCreating = false;
}}
>
<X size={16} class="mr-2" /> Cancelar
</Button>
<Button onclick={saveChanges}>
<Save size={16} class="mr-2" /> Guardar Cambios
</Button>
</div>
</div>
{:else}
<div class="flex flex-col gap-4">
<div class="flex items-center justify-between">
<h2 class="text-2xl font-bold">{selectedArticle.title}</h2>
{#if isAdmin}
<Button variant="outline" size="sm" onclick={startEdit}>
<Edit2 size={16} class="mr-2" /> Editar
</Button>
{/if}
</div>
<div class="prose prose-sm max-w-none border-t pt-4 dark:prose-invert">
{@html renderMarkdown(selectedArticle.content)}
</div>
</div>
{/if}
</div>
{/if}
</div>
{/if}
</div>
</Sheet.Content>
</Sheet.Root>

View File

@@ -49,7 +49,8 @@ export function createSvelteTable<TData extends RowData>(options: TableOptions<T
);
const table = createTable(resolvedOptions);
let state = $state<Partial<TableState>>(table.initialState);
// Use JSON parse/stringify to ensure we get a clean, non-proxy initial state object
let state = $state<Partial<TableState>>(JSON.parse(JSON.stringify(table.initialState)));
function updateOptions() {
table.setOptions((prev) => {
@@ -105,8 +106,7 @@ export function mergeObjects<Sources extends readonly MaybeThunk<any>[]>(
return new Proxy(Object.create(null), {
get(_, key) {
const src = findSourceWithKey(key);
return src?.[key as never];
return src ? src[key as never] : undefined;
},
has(_, key) {