fix(journals): add type='button' to prevent form submission and migrate to V3 Action API for file downloads

This commit is contained in:
Scott Idem
2026-02-03 22:14:22 -05:00
parent 6abe4c897e
commit 281972cb5d
24 changed files with 104 additions and 132 deletions

View File

@@ -121,16 +121,16 @@
<div class="space-y-6 py-2 h-[60vh] overflow-y-auto px-4">
<!-- Navigation Tabs -->
<div class="flex justify-center gap-1 mb-4 p-1 bg-surface-500/10 rounded-lg max-w-fit mx-auto sticky top-0 z-10 backdrop-blur-sm">
<button class="btn btn-sm transition-all {tab === 'actions' ? 'variant-filled-primary' : 'variant-soft-surface'}" onclick={() => (tab = 'actions')}>
<button type="button" class="btn btn-sm transition-all {tab === 'actions' ? 'variant-filled-primary' : 'variant-soft-surface'}" onclick={() => (tab = 'actions')}>
<Zap size="1.1em" class="mr-1" /> Quick Actions
</button>
<button class="btn btn-sm transition-all {tab === 'meta' ? 'variant-filled-primary' : 'variant-soft-surface'}" onclick={() => (tab = 'meta')}>
<button type="button" class="btn btn-sm transition-all {tab === 'meta' ? 'variant-filled-primary' : 'variant-soft-surface'}" onclick={() => (tab = 'meta')}>
<Shapes size="1.1em" class="mr-1" /> Metadata
</button>
<button class="btn btn-sm transition-all {tab === 'security' ? 'variant-filled-primary' : 'variant-soft-surface'}" onclick={() => (tab = 'security')}>
<button type="button" class="btn btn-sm transition-all {tab === 'security' ? 'variant-filled-primary' : 'variant-soft-surface'}" onclick={() => (tab = 'security')}>
<ShieldCheck size="1.1em" class="mr-1" /> Status & Security
</button>
<button class="btn btn-sm transition-all {tab === 'json' ? 'variant-filled-primary' : 'variant-soft-surface'}" onclick={() => (tab = 'json')}>
<button type="button" class="btn btn-sm transition-all {tab === 'json' ? 'variant-filled-primary' : 'variant-soft-surface'}" onclick={() => (tab = 'json')}>
<CodeXml size="1.1em" class="mr-1" /> JSON
</button>
</div>
@@ -138,16 +138,16 @@
{#if tab === 'actions'}
<div class="space-y-6 animate-in fade-in duration-300">
<section class="grid grid-cols-1 md:grid-cols-2 gap-4">
<button class="btn variant-soft-secondary w-full" onclick={() => { show = false; on_prepend?.(); }}>
<button type="button" class="btn variant-soft-secondary w-full" onclick={() => { show = false; on_prepend?.(); }}>
<ArrowUpToLine size="1.2em" class="mr-2"/> Prepend Content
</button>
<button class="btn variant-soft-secondary w-full" onclick={() => { show = false; on_append?.(); }}>
<button type="button" class="btn variant-soft-secondary w-full" onclick={() => { show = false; on_append?.(); }}>
<ArrowDownToLine size="1.2em" class="mr-2"/> Append Content
</button>
<button class="btn variant-soft-surface w-full" onclick={() => { show = false; on_show_export?.(); }}>
<button type="button" class="btn variant-soft-surface w-full" onclick={() => { show = false; on_show_export?.(); }}>
<FileDown size="1.2em" class="mr-2"/> Export Entry
</button>
<button class="btn variant-soft-surface w-full" onclick={() => { /* Clone logic here */ alert('Clone not yet implemented in modal'); }}>
<button type="button" class="btn variant-soft-surface w-full" onclick={() => { /* Clone logic here */ alert('Clone not yet implemented in modal'); }}>
<Copy size="1.2em" class="mr-2"/> Clone Entry
</button>
</section>
@@ -156,7 +156,7 @@
<h4 class="text-xs font-bold uppercase opacity-50">Quick Category</h4>
<div class="flex flex-wrap gap-2">
{#each journal?.cfg_json?.category_li ?? [] as cat}
<button
<button type="button"
class="btn btn-sm {tmp_entry_obj.category_code === cat.code ? 'variant-filled-primary' : 'variant-soft-primary'}"
onclick={() => { tmp_entry_obj.category_code = cat.code; handle_update_entry(); on_save(); }}
>
@@ -195,9 +195,9 @@
<label class="label">
<span class="text-sm font-bold opacity-70">Sort Priority</span>
<div class="flex items-center gap-2">
<button class="btn-icon btn-icon-sm variant-soft-surface" onclick={() => { tmp_entry_obj.sort = (tmp_entry_obj.sort ?? 0) - 1; handle_update_entry(); on_save(); }}><Minus size="1em"/></button>
<button type="button" class="btn-icon btn-icon-sm variant-soft-surface" onclick={() => { tmp_entry_obj.sort = (tmp_entry_obj.sort ?? 0) - 1; handle_update_entry(); on_save(); }}><Minus size="1em"/></button>
<span class="font-mono font-bold w-8 text-center">{tmp_entry_obj.sort ?? 0}</span>
<button class="btn-icon btn-icon-sm variant-soft-surface" onclick={() => { tmp_entry_obj.sort = (tmp_entry_obj.sort ?? 0) + 1; handle_update_entry(); on_save(); }}><Plus size="1em"/></button>
<button type="button" class="btn-icon btn-icon-sm variant-soft-surface" onclick={() => { tmp_entry_obj.sort = (tmp_entry_obj.sort ?? 0) + 1; handle_update_entry(); on_save(); }}><Plus size="1em"/></button>
</div>
</label>
</div>
@@ -238,9 +238,9 @@
<span class="text-xs opacity-60">Manual list position</span>
</div>
<div class="flex items-center gap-2">
<button class="btn-icon btn-icon-sm variant-soft-surface" onclick={() => { tmp_entry_obj.sort = (tmp_entry_obj.sort ?? 0) - 1; handle_update_entry(); on_save(); }}><Minus size="1em"/></button>
<button type="button" class="btn-icon btn-icon-sm variant-soft-surface" onclick={() => { tmp_entry_obj.sort = (tmp_entry_obj.sort ?? 0) - 1; handle_update_entry(); on_save(); }}><Minus size="1em"/></button>
<span class="font-mono font-bold w-8 text-center text-lg">{tmp_entry_obj.sort ?? 0}</span>
<button class="btn-icon btn-icon-sm variant-soft-surface" onclick={() => { tmp_entry_obj.sort = (tmp_entry_obj.sort ?? 0) + 1; handle_update_entry(); on_save(); }}><Plus size="1em"/></button>
<button type="button" class="btn-icon btn-icon-sm variant-soft-surface" onclick={() => { tmp_entry_obj.sort = (tmp_entry_obj.sort ?? 0) + 1; handle_update_entry(); on_save(); }}><Plus size="1em"/></button>
</div>
</div>
</div>
@@ -267,7 +267,7 @@
<RefreshCcw size="1.2em" /> Disaster Recovery
</h4>
<p class="text-xs opacity-70 mb-4 italic">If the encryption passcode is lost, the data is unrecoverable. You can force a reset to plain text to reuse this entry ID.</p>
<button class="btn btn-sm variant-filled-error w-full font-bold" onclick={() => { show = false; on_force_reset?.(); }}>
<button type="button" class="btn btn-sm variant-filled-error w-full font-bold" onclick={() => { show = false; on_force_reset?.(); }}>
Force Reset to Plain Text
</button>
</div>
@@ -275,7 +275,7 @@
{/if}
<section class="pt-12">
<button class="btn btn-sm variant-soft-error w-full" onclick={() => { alert('Delete logic handled in parent component'); }}>
<button type="button" class="btn btn-sm variant-soft-error w-full" onclick={() => { alert('Delete logic handled in parent component'); }}>
<Trash2 size="1.1em" class="mr-2" /> Delete Entry
</button>
</section>
@@ -294,7 +294,7 @@
</div>
{#snippet footer()}
<button class="btn variant-filled-primary font-bold shadow-lg min-w-[120px]" onclick={() => (show = false)}>
<button type="button" class="btn variant-filled-primary font-bold shadow-lg min-w-[120px]" onclick={() => (show = false)}>
<Check size="1.2em" class="mr-2" />
Done
</button>