Prettier for Journals
This commit is contained in:
@@ -1,265 +1,265 @@
|
||||
<script lang="ts">
|
||||
// *** Import Svelte specific
|
||||
import { goto } from '$app/navigation';
|
||||
// *** Import Svelte specific
|
||||
import { goto } from '$app/navigation';
|
||||
|
||||
// *** Import other supporting libraries
|
||||
import { BookOpenText, BookPlus, FileDown, FilePlus, FileUp, LoaderCircle, Menu, Pencil, Settings } from '@lucide/svelte';
|
||||
// *** Import Aether specific variables and functions
|
||||
import { ae_util } from '$lib/ae_utils/ae_utils';
|
||||
import {
|
||||
ae_snip,
|
||||
ae_loc,
|
||||
ae_sess,
|
||||
ae_api,
|
||||
ae_trig,
|
||||
slct,
|
||||
slct_trigger
|
||||
} from '$lib/stores/ae_stores';
|
||||
import {
|
||||
journals_loc,
|
||||
journals_sess,
|
||||
journals_slct,
|
||||
journals_trig,
|
||||
journals_prom
|
||||
} from '$lib/ae_journals/ae_journals_stores';
|
||||
import { journals_func } from '$lib/ae_journals/ae_journals_functions';
|
||||
import Journal_obj_id_edit from './ae_comp__journal_obj_id_edit.svelte';
|
||||
// *** Import other supporting libraries
|
||||
import {
|
||||
BookOpenText,
|
||||
BookPlus,
|
||||
FileDown,
|
||||
FilePlus,
|
||||
FileUp,
|
||||
LoaderCircle,
|
||||
Menu,
|
||||
Pencil,
|
||||
Settings
|
||||
} from '@lucide/svelte';
|
||||
// *** Import Aether specific variables and functions
|
||||
import { ae_util } from '$lib/ae_utils/ae_utils';
|
||||
import {
|
||||
ae_snip,
|
||||
ae_loc,
|
||||
ae_sess,
|
||||
ae_api,
|
||||
ae_trig,
|
||||
slct,
|
||||
slct_trigger
|
||||
} from '$lib/stores/ae_stores';
|
||||
import {
|
||||
journals_loc,
|
||||
journals_sess,
|
||||
journals_slct,
|
||||
journals_trig,
|
||||
journals_prom
|
||||
} from '$lib/ae_journals/ae_journals_stores';
|
||||
import { journals_func } from '$lib/ae_journals/ae_journals_functions';
|
||||
import Journal_obj_id_edit from './ae_comp__journal_obj_id_edit.svelte';
|
||||
|
||||
interface Props {
|
||||
log_lvl?: number;
|
||||
lq__journal_obj: any;
|
||||
lq__journal_entry_obj_li: any;
|
||||
on_show_export?: () => void;
|
||||
on_show_import?: () => void;
|
||||
interface Props {
|
||||
log_lvl?: number;
|
||||
lq__journal_obj: any;
|
||||
lq__journal_entry_obj_li: any;
|
||||
on_show_export?: () => void;
|
||||
on_show_import?: () => void;
|
||||
}
|
||||
|
||||
let {
|
||||
log_lvl = 0,
|
||||
lq__journal_obj,
|
||||
lq__journal_entry_obj_li,
|
||||
on_show_export,
|
||||
on_show_import
|
||||
}: Props = $props();
|
||||
|
||||
// let ae_promises: key_val = {};
|
||||
// let ae_tmp: key_val = {};
|
||||
// let ae_trigger: any = null;
|
||||
// let ae_triggers: key_val = {};
|
||||
|
||||
let typed_journal_passcode: string = $state('');
|
||||
let passcode_timer: any = $state(null);
|
||||
|
||||
$effect(() => {
|
||||
if (typed_journal_passcode?.length > 4) {
|
||||
if (!$journals_sess?.journal_kv) {
|
||||
$journals_sess.journal_kv = {};
|
||||
}
|
||||
if (!$journals_sess.journal_kv[$lq__journal_obj?.id]) {
|
||||
$journals_sess.journal_kv[$lq__journal_obj?.id] = {};
|
||||
}
|
||||
|
||||
verify_journal_passcode();
|
||||
}
|
||||
|
||||
let {
|
||||
log_lvl = 0,
|
||||
lq__journal_obj,
|
||||
lq__journal_entry_obj_li,
|
||||
on_show_export,
|
||||
on_show_import
|
||||
}: Props = $props();
|
||||
|
||||
// let ae_promises: key_val = {};
|
||||
// let ae_tmp: key_val = {};
|
||||
// let ae_trigger: any = null;
|
||||
// let ae_triggers: key_val = {};
|
||||
|
||||
let typed_journal_passcode: string = $state('');
|
||||
let passcode_timer: any = $state(null);
|
||||
|
||||
$effect(() => {
|
||||
if (typed_journal_passcode?.length > 4) {
|
||||
if (!$journals_sess?.journal_kv) {
|
||||
$journals_sess.journal_kv = {};
|
||||
}
|
||||
if (!$journals_sess.journal_kv[$lq__journal_obj?.id]) {
|
||||
$journals_sess.journal_kv[$lq__journal_obj?.id] = {};
|
||||
}
|
||||
|
||||
verify_journal_passcode();
|
||||
}
|
||||
|
||||
// We need to set a timeout to force the user to re-enter their private passcode
|
||||
if (
|
||||
$lq__journal_obj?.id &&
|
||||
$journals_sess?.journal_kv[$lq__journal_obj?.id] &&
|
||||
$journals_sess?.journal_kv[$lq__journal_obj?.id]
|
||||
?.journal_passcode_verified
|
||||
) {
|
||||
if (passcode_timer) {
|
||||
if (log_lvl) {
|
||||
console.log('Passcode timer already set');
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Use journal.passcode_timeout (assuming it's in minutes, default to 5)
|
||||
const timeout_minutes = $lq__journal_obj?.passcode_timeout ?? 5;
|
||||
const timeout_ms = 1000 * 60 * timeout_minutes;
|
||||
|
||||
// We need to set a timeout to force the user to re-enter their private passcode
|
||||
if (
|
||||
$lq__journal_obj?.id &&
|
||||
$journals_sess?.journal_kv[$lq__journal_obj?.id] &&
|
||||
$journals_sess?.journal_kv[$lq__journal_obj?.id]
|
||||
?.journal_passcode_verified
|
||||
) {
|
||||
if (passcode_timer) {
|
||||
if (log_lvl) {
|
||||
console.log(
|
||||
`Setting passcode timer for ${timeout_minutes} minutes (${timeout_ms}ms)`
|
||||
);
|
||||
console.log('Passcode timer already set');
|
||||
}
|
||||
|
||||
passcode_timer = setTimeout(() => {
|
||||
if (log_lvl) {
|
||||
console.log('Passcode timer expired');
|
||||
}
|
||||
typed_journal_passcode = '';
|
||||
if (!$journals_sess?.journal_kv[$lq__journal_obj?.id]) {
|
||||
$journals_sess.journal_kv[$lq__journal_obj?.id] = {};
|
||||
}
|
||||
|
||||
// Reset verification and decryption flags
|
||||
$journals_sess.journal_kv[
|
||||
$lq__journal_obj?.id
|
||||
].journal_passcode_verified = false;
|
||||
$journals_sess.journal_kv[
|
||||
$lq__journal_obj?.id
|
||||
].journal_passcode_decrypted = false;
|
||||
|
||||
passcode_timer = null;
|
||||
}, timeout_ms);
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
function verify_journal_passcode() {
|
||||
// Use journal.passcode_timeout (assuming it's in minutes, default to 5)
|
||||
const timeout_minutes = $lq__journal_obj?.passcode_timeout ?? 5;
|
||||
const timeout_ms = 1000 * 60 * timeout_minutes;
|
||||
|
||||
if (log_lvl) {
|
||||
console.log(
|
||||
`verify_journal_passcode: typed_journal_passcode = ${typed_journal_passcode} journal private passcode = ${$lq__journal_obj?.private_passcode}`
|
||||
`Setting passcode timer for ${timeout_minutes} minutes (${timeout_ms}ms)`
|
||||
);
|
||||
}
|
||||
|
||||
if (typed_journal_passcode === $lq__journal_obj?.private_passcode) {
|
||||
console.log('Matched journal private passcode');
|
||||
passcode_timer = setTimeout(() => {
|
||||
if (log_lvl) {
|
||||
console.log('Passcode timer expired');
|
||||
}
|
||||
typed_journal_passcode = '';
|
||||
if (!$journals_sess?.journal_kv[$lq__journal_obj?.id]) {
|
||||
$journals_sess.journal_kv[$lq__journal_obj?.id] = {};
|
||||
}
|
||||
$journals_sess.journal_kv[$lq__journal_obj?.id] = {
|
||||
typed_journal_passcode: typed_journal_passcode,
|
||||
journal_passcode_verified: true
|
||||
};
|
||||
|
||||
typed_journal_passcode = '';
|
||||
} else {
|
||||
}
|
||||
// Reset verification and decryption flags
|
||||
$journals_sess.journal_kv[
|
||||
$lq__journal_obj?.id
|
||||
].journal_passcode_verified = false;
|
||||
$journals_sess.journal_kv[
|
||||
$lq__journal_obj?.id
|
||||
].journal_passcode_decrypted = false;
|
||||
|
||||
passcode_timer = null;
|
||||
}, timeout_ms);
|
||||
}
|
||||
});
|
||||
|
||||
function verify_journal_passcode() {
|
||||
if (log_lvl) {
|
||||
console.log(
|
||||
`verify_journal_passcode: typed_journal_passcode = ${typed_journal_passcode} journal private passcode = ${$lq__journal_obj?.private_passcode}`
|
||||
);
|
||||
}
|
||||
|
||||
async function handle_new_entry() {
|
||||
let data_kv = {
|
||||
category_code: null
|
||||
if (typed_journal_passcode === $lq__journal_obj?.private_passcode) {
|
||||
console.log('Matched journal private passcode');
|
||||
if (!$journals_sess?.journal_kv[$lq__journal_obj?.id]) {
|
||||
$journals_sess.journal_kv[$lq__journal_obj?.id] = {};
|
||||
}
|
||||
$journals_sess.journal_kv[$lq__journal_obj?.id] = {
|
||||
typed_journal_passcode: typed_journal_passcode,
|
||||
journal_passcode_verified: true
|
||||
};
|
||||
if ($journals_loc.entry.qry__category_code) {
|
||||
data_kv.category_code = $journals_loc.entry.qry__category_code;
|
||||
}
|
||||
|
||||
try {
|
||||
const results = await journals_func.create_ae_obj__journal_entry({
|
||||
api_cfg: $ae_api,
|
||||
journal_id: $lq__journal_obj?.journal_id,
|
||||
data_kv: data_kv,
|
||||
log_lvl: log_lvl
|
||||
});
|
||||
|
||||
if (results?.journal_entry_id) {
|
||||
$journals_slct.journal_entry_id =
|
||||
results.journal_entry_id;
|
||||
$journals_loc.entry.edit_kv[$journals_slct.journal_entry_id] =
|
||||
'current';
|
||||
goto(
|
||||
`/journals/${$lq__journal_obj?.journal_id}/entry/${results.journal_entry_id}`
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error creating journal entry:', error);
|
||||
alert('Failed to create new journal entry.');
|
||||
}
|
||||
typed_journal_passcode = '';
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
async function handle_new_entry() {
|
||||
let data_kv = {
|
||||
category_code: null
|
||||
};
|
||||
if ($journals_loc.entry.qry__category_code) {
|
||||
data_kv.category_code = $journals_loc.entry.qry__category_code;
|
||||
}
|
||||
|
||||
try {
|
||||
const results = await journals_func.create_ae_obj__journal_entry({
|
||||
api_cfg: $ae_api,
|
||||
journal_id: $lq__journal_obj?.journal_id,
|
||||
data_kv: data_kv,
|
||||
log_lvl: log_lvl
|
||||
});
|
||||
|
||||
if (results?.journal_entry_id) {
|
||||
$journals_slct.journal_entry_id = results.journal_entry_id;
|
||||
$journals_loc.entry.edit_kv[$journals_slct.journal_entry_id] =
|
||||
'current';
|
||||
goto(
|
||||
`/journals/${$lq__journal_obj?.journal_id}/entry/${results.journal_entry_id}`
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error creating journal entry:', error);
|
||||
alert('Failed to create new journal entry.');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="relative group/view w-full mx-2 my-1">
|
||||
<div class="group/view relative mx-2 my-1 w-full">
|
||||
<!-- Glow ring — mirrors Quick Add and Journal List -->
|
||||
<div
|
||||
class="absolute -inset-1 bg-linear-to-r from-primary-500 to-secondary-500
|
||||
rounded-2xl blur opacity-10 dark:opacity-20
|
||||
group-hover/view:opacity-25 dark:group-hover/view:opacity-35
|
||||
transition duration-700 pointer-events-none"
|
||||
></div>
|
||||
class="from-primary-500 to-secondary-500 pointer-events-none absolute -inset-1
|
||||
rounded-2xl bg-linear-to-r opacity-10 blur
|
||||
transition duration-700
|
||||
group-hover/view:opacity-25 dark:opacity-20 dark:group-hover/view:opacity-35">
|
||||
</div>
|
||||
<section
|
||||
class="relative rounded-xl p-3 w-full
|
||||
flex flex-col gap-2 items-center justify-center
|
||||
bg-white dark:bg-gray-900
|
||||
border border-gray-200 dark:border-gray-700
|
||||
text-gray-900 dark:text-gray-100
|
||||
shadow-xl"
|
||||
bind:clientHeight={$ae_loc.iframe_height_modal_body}
|
||||
>
|
||||
<header
|
||||
class="ae_header journal__header flex flex-row flex-wrap gap-2 items-center justify-between w-full"
|
||||
>
|
||||
<h2 class="journal__name h3 text-center">
|
||||
<BookOpenText class="inline-block text-primary-500/80" />
|
||||
{@html $lq__journal_obj?.name ?? 'Loading...'}
|
||||
class="relative flex w-full flex-col
|
||||
items-center justify-center gap-2 rounded-xl border
|
||||
border-gray-200 bg-white
|
||||
p-3 text-gray-900 shadow-xl
|
||||
dark:border-gray-700 dark:bg-gray-900
|
||||
dark:text-gray-100"
|
||||
bind:clientHeight={$ae_loc.iframe_height_modal_body}>
|
||||
<header
|
||||
class="ae_header journal__header flex w-full flex-row flex-wrap items-center justify-between gap-2">
|
||||
<h2 class="journal__name h3 text-center">
|
||||
<BookOpenText class="text-primary-500/80 inline-block" />
|
||||
{@html $lq__journal_obj?.name ?? 'Loading...'}
|
||||
|
||||
{#if $ae_loc.edit_mode}
|
||||
<span
|
||||
class="badge preset-tonal-success font-bold text-lg px-2 ml-2"
|
||||
title="Entries matching current filters"
|
||||
>
|
||||
{$lq__journal_entry_obj_li?.length ?? '0'}<span
|
||||
class="text-xs opacity-50 ml-0.5">×</span
|
||||
>
|
||||
</span>
|
||||
{/if}
|
||||
{#if $ae_loc.edit_mode}
|
||||
<span
|
||||
class="badge preset-tonal-success ml-2 px-2 text-lg font-bold"
|
||||
title="Entries matching current filters">
|
||||
{$lq__journal_entry_obj_li?.length ?? '0'}<span
|
||||
class="ml-0.5 text-xs opacity-50">×</span>
|
||||
</span>
|
||||
{/if}
|
||||
|
||||
{#await $journals_prom.load__journal_entry_obj_li}
|
||||
<LoaderCircle
|
||||
size="1em"
|
||||
class="inline-block animate-spin ml-1 text-primary-500"
|
||||
/>
|
||||
{/await}
|
||||
</h2>
|
||||
{#await $journals_prom.load__journal_entry_obj_li}
|
||||
<LoaderCircle
|
||||
size="1em"
|
||||
class="text-primary-500 ml-1 inline-block animate-spin" />
|
||||
{/await}
|
||||
</h2>
|
||||
|
||||
<div
|
||||
class="grow flex flex-row flex-wrap gap-2 items-center justify-end"
|
||||
>
|
||||
<!-- Simplified Config Trigger -->
|
||||
<button
|
||||
type="button"
|
||||
onclick={() =>
|
||||
($journals_sess.show__modal_edit__journal_obj = true)}
|
||||
class="btn preset-tonal-secondary py-1 px-3 shadow-md"
|
||||
title="Journal Config & Actions"
|
||||
>
|
||||
<Settings size="1.2em" class="mr-2" />
|
||||
<span class="hidden md:inline">Config</span>
|
||||
</button>
|
||||
<div
|
||||
class="flex grow flex-row flex-wrap items-center justify-end gap-2">
|
||||
<!-- Simplified Config Trigger -->
|
||||
<button
|
||||
type="button"
|
||||
onclick={() =>
|
||||
($journals_sess.show__modal_edit__journal_obj = true)}
|
||||
class="btn preset-tonal-secondary px-3 py-1 shadow-md"
|
||||
title="Journal Config & Actions">
|
||||
<Settings size="1.2em" class="mr-2" />
|
||||
<span class="hidden md:inline">Config</span>
|
||||
</button>
|
||||
|
||||
<!-- Passcode Verification (Condensed) -->
|
||||
{#if !$journals_sess?.journal_kv[$lq__journal_obj?.id]?.journal_passcode_verified}
|
||||
<div class="flex gap-1">
|
||||
<input
|
||||
autocomplete="off"
|
||||
type="text"
|
||||
bind:value={typed_journal_passcode}
|
||||
placeholder="Passcode"
|
||||
class="input input-sm w-32"
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</header>
|
||||
<!-- Passcode Verification (Condensed) -->
|
||||
{#if !$journals_sess?.journal_kv[$lq__journal_obj?.id]?.journal_passcode_verified}
|
||||
<div class="flex gap-1">
|
||||
<input
|
||||
autocomplete="off"
|
||||
type="text"
|
||||
bind:value={typed_journal_passcode}
|
||||
placeholder="Passcode"
|
||||
class="input input-sm w-32" />
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- Show Journal description -->
|
||||
{#if $lq__journal_obj?.description && $ae_loc.edit_mode}
|
||||
<div
|
||||
class="
|
||||
<!-- Show Journal description -->
|
||||
{#if $lq__journal_obj?.description && $ae_loc.edit_mode}
|
||||
<div
|
||||
class="
|
||||
prose
|
||||
space-y-1
|
||||
p-2
|
||||
w-full max-w-(--breakpoint-sm) md:max-w-(--breakpoint-md)
|
||||
font-mono
|
||||
bg-gray-50 text-gray-900
|
||||
dark:bg-gray-800 dark:text-gray-100
|
||||
shadow-md rounded-lg
|
||||
text-sm font-normal text-wrap word-break
|
||||
|
||||
prose-p:m-0 prose-p:p-0
|
||||
prose-h1:underline prose-h1:decoration-double
|
||||
word-break
|
||||
prose-p:m-0
|
||||
prose-p:p-0 prose-h1:underline prose-h1:decoration-double
|
||||
prose-h2:underline
|
||||
prose-h1:text-2xl prose-h2:text-xl prose-h3:text-lg
|
||||
prose-h1:m-0 prose-h2:m-0 prose-h3:m-0 prose-h4:m-0 prose-h5:m-0 prose-h6:m-0
|
||||
prose-h1:text-2xl prose-h2:text-xl
|
||||
prose-h3:text-lg prose-h1:m-0
|
||||
prose-h2:m-0 prose-h3:m-0
|
||||
prose-h4:m-0 prose-h5:m-0 prose-h6:m-0 prose-li:m-0
|
||||
|
||||
prose-li:m-0 prose-li:p-0 prose-li:line-height-none
|
||||
"
|
||||
>
|
||||
{@html $lq__journal_obj.description_md_html}
|
||||
</div>
|
||||
{/if}
|
||||
prose-li:p-0 prose-li:line-height-none
|
||||
w-full max-w-(--breakpoint-sm)
|
||||
space-y-1
|
||||
rounded-lg bg-gray-50 p-2
|
||||
font-mono text-sm font-normal text-wrap text-gray-900 shadow-md
|
||||
|
||||
md:max-w-(--breakpoint-md) dark:bg-gray-800 dark:text-gray-100
|
||||
">
|
||||
{@html $lq__journal_obj.description_md_html}
|
||||
</div>
|
||||
{/if}
|
||||
</section>
|
||||
</div>
|
||||
|
||||
@@ -270,5 +270,4 @@
|
||||
bind:show={$journals_sess.show__modal_edit__journal_obj}
|
||||
on_new_entry={handle_new_entry}
|
||||
{on_show_export}
|
||||
{on_show_import}
|
||||
/>
|
||||
{on_show_import} />
|
||||
|
||||
Reference in New Issue
Block a user