- Replace all Skeleton v2 variant-* classes with v4 preset-* equivalents - variant-filled-* → preset-filled-* - variant-soft-* / variant-ghost-* → preset-tonal-* - variant-outline-* → preset-outlined-* - variant-form-material removed from inputs/selects/textareas - input-bordered removed - Fix dark mode: journal entry content hover (dark:hover:bg-blue-950) - Fix dark mode: journal obj view section/description bg and text colors - Fix modal headers: add dismissable=false + explicit X close button (all 3 journals modals) - Fix DaisyUI wrappers removed from modal_journal_entry_append - app.css: add global select padding-inline to fix text-against-border issue
159 lines
5.1 KiB
Svelte
159 lines
5.1 KiB
Svelte
<script lang="ts">
|
|
import { api } from '$lib/api/api';
|
|
import { ae_api } from '$lib/stores/ae_stores';
|
|
import {
|
|
journals_slct,
|
|
journals_loc,
|
|
journals_trig
|
|
} from '$lib/ae_journals/ae_journals_stores';
|
|
import { journals_func } from '$lib/ae_journals/ae_journals_functions';
|
|
import { BookType } from 'lucide-svelte';
|
|
|
|
// Props
|
|
let {
|
|
class: className = '',
|
|
placeholder = 'Type your quick note... (First line = Title)',
|
|
journals_li = [] // Optional list of journals to select from
|
|
} = $props();
|
|
|
|
// State
|
|
let note_content = $state('');
|
|
let is_submitting = $state(false);
|
|
|
|
// Derived / Local target
|
|
// We prefer the persisted 'qry__journal_id' if we are on the main landing page
|
|
let selected_journal_id = $state($journals_loc.entry.qry__journal_id);
|
|
|
|
// If a journal is explicitly selected via slct (e.g. we are in a journal view), use that
|
|
let target_journal_id = $derived(
|
|
$journals_slct.journal_id || selected_journal_id
|
|
);
|
|
|
|
async function handle_submit() {
|
|
if (!note_content.trim()) return;
|
|
if (!target_journal_id) {
|
|
alert('Please select a target journal first.');
|
|
return;
|
|
}
|
|
|
|
is_submitting = true;
|
|
|
|
const lines = note_content.trim().split('\n');
|
|
let name = lines[0].substring(0, 100);
|
|
if (lines[0].length > 100) name += '...';
|
|
|
|
// Remove the first line (title) from the content
|
|
const entry_content = lines.slice(1).join('\n').trim();
|
|
|
|
const data_kv = {
|
|
name: name,
|
|
content: entry_content,
|
|
type_code: 'note',
|
|
private: false, // Ensure notes are public/decrypted by default
|
|
enable: true,
|
|
hide: false
|
|
};
|
|
|
|
try {
|
|
const res = await journals_func.create_ae_obj__journal_entry({
|
|
api_cfg: $ae_api,
|
|
journal_id: target_journal_id, // Pass string ID here
|
|
data_kv: data_kv,
|
|
log_lvl: 1
|
|
});
|
|
|
|
if (res) {
|
|
note_content = '';
|
|
// Trigger refresh
|
|
$journals_trig.journal_entry_li = true;
|
|
} else {
|
|
alert('Failed to create note.');
|
|
}
|
|
} catch (error) {
|
|
console.error('Error creating journal entry:', error);
|
|
alert('Failed to create note.');
|
|
}
|
|
|
|
is_submitting = false;
|
|
}
|
|
|
|
function handle_keydown(e: KeyboardEvent) {
|
|
if (e.ctrlKey && e.key === 'Enter') {
|
|
handle_submit();
|
|
}
|
|
}
|
|
|
|
function handle_journal_change(e: Event) {
|
|
const val = (e.target as HTMLSelectElement).value;
|
|
selected_journal_id = val;
|
|
$journals_loc.entry.qry__journal_id = val; // Persist choice
|
|
}
|
|
</script>
|
|
|
|
<div class="card p-4 space-y-4 preset-tonal-surface {className}">
|
|
<header
|
|
class="flex flex-col sm:flex-row justify-between items-start sm:items-center gap-2"
|
|
>
|
|
<h3 class="h3 flex items-center gap-2">
|
|
<BookType size="1.2em" class="text-primary-500" />
|
|
Quick Add
|
|
</h3>
|
|
|
|
{#if journals_li && journals_li.length > 0}
|
|
<div class="w-full sm:w-auto">
|
|
<select
|
|
class="select select-sm font-bold"
|
|
value={target_journal_id}
|
|
onchange={handle_journal_change}
|
|
>
|
|
<option value="" disabled selected={!target_journal_id}
|
|
>Select Target Journal...</option
|
|
>
|
|
{#each journals_li as journal (journal.id)}
|
|
<option value={journal.id}>{journal.name}</option>
|
|
{/each}
|
|
</select>
|
|
</div>
|
|
{:else if !target_journal_id}
|
|
<span class="badge preset-tonal-error">No Journal Selected</span>
|
|
{/if}
|
|
</header>
|
|
|
|
<textarea
|
|
class="textarea"
|
|
rows="3"
|
|
bind:value={note_content}
|
|
{placeholder}
|
|
onkeydown={handle_keydown}
|
|
disabled={is_submitting}
|
|
></textarea>
|
|
|
|
<div class="flex justify-between items-center">
|
|
<span
|
|
class="text-[10px] opacity-50 font-mono uppercase tracking-tighter hidden sm:block"
|
|
>
|
|
Press Ctrl + Enter to save
|
|
</span>
|
|
<div class="flex justify-end space-x-2 grow sm:grow-0">
|
|
<button
|
|
type="button"
|
|
class="btn btn-sm preset-tonal-surface"
|
|
onclick={() => (note_content = '')}
|
|
disabled={is_submitting || note_content.length === 0}
|
|
>
|
|
Clear
|
|
</button>
|
|
<button
|
|
type="button"
|
|
class="btn btn-sm preset-filled-primary font-bold"
|
|
onclick={handle_submit}
|
|
disabled={is_submitting ||
|
|
!target_journal_id ||
|
|
note_content.length === 0}
|
|
>
|
|
{#if is_submitting}Saving...{:else}Add Note{/if}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|