Work on hiding certain entries by default. Ability to append to an entry.

This commit is contained in:
Scott Idem
2025-04-14 18:33:59 -04:00
parent 2133fa520e
commit 3a47b77641
3 changed files with 354 additions and 18 deletions

View File

@@ -7,16 +7,18 @@ let { data, children } = $props();
import { goto } from '$app/navigation';
import {
ArrowDown01, ArrowDown10, ArrowDownUp,
BookHeart, BookImage, Bookmark, BookOpenText,
BookHeart, BookImage, Bookmark, BookOpenText, BriefcaseBusiness,
Check,
Eye, EyeOff,
Flag, FlagOff, FilePlus, Library,
Flag, FlagOff, FilePlus, Fingerprint,
Globe,
Library,
MessageSquareWarning, Minus,
Notebook,
Pencil, Plus,
SquareLibrary,
Shapes, Share2, ShieldCheck, ShieldMinus, Siren, Skull,
Tags, Trash2, TypeOutline,
Tags, ToggleLeft, ToggleRight, Trash2, TypeOutline,
X
} from '@lucide/svelte';
@@ -314,6 +316,8 @@ async function handle_update_journal() {
</section>
<!-- Modal for editing journal -->
{#if $journals_sess.show__modal_edit__journal_obj}
<Modal
@@ -415,13 +419,13 @@ async function handle_update_journal() {
Journal Entry List Max Height:
</span>
<select
class="btn btn-sm variant-ghost-surface hover:variant-filled-surface transition text-xs w-full mb-2 max-w-96"
bind:value={$journals_slct.tmp_journal_obj.cfg_json.entry_li_max_height}
title="Select maximum height for journal entries in the list"
onchange={(event) => {
$journals_slct.tmp_journal_obj.cfg_json.entry_li_max_height = event.target.value;
console.log('Selected max height:', $journals_slct.tmp_journal_obj.cfg_json.entry_li_max_height);
}}
class="btn btn-sm variant-ghost-surface hover:variant-filled-surface transition text-xs w-full mb-2 max-w-96"
title="Select maximum height for journal entries in the list"
>
<option value="">Default (auto)</option>
<!-- <option value="none">None (no limit)</option> -->
@@ -442,13 +446,13 @@ async function handle_update_journal() {
Color Scheme:
</span>
<select
class="btn btn-sm variant-ghost-surface hover:variant-filled-surface transition text-xs w-full mb-2 max-w-96"
bind:value={$journals_slct.tmp_journal_obj.cfg_json.color_scheme}
title="Select color scheme for journal entries"
onchange={(event) => {
$journals_slct.tmp_journal_obj.cfg_json.color_scheme = event.target.value;
console.log('Selected color scheme:', $journals_slct.tmp_journal_obj.cfg_json.color_scheme);
}}
class="btn btn-sm variant-ghost-surface hover:variant-filled-surface transition text-xs w-full mb-2 max-w-96"
title="Select color scheme for journal entries"
>
<option value="">Default (auto)</option>
<option value="slate">Slate</option>
@@ -461,6 +465,92 @@ async function handle_update_journal() {
</select>
</div>
<!-- Toggles for automatically hiding Entries marked as either: private, personal, or professional -->
<button
type="button"
onclick={() => {
$journals_slct.tmp_journal_obj.cfg_json.hide_private = !$journals_slct.tmp_journal_obj.cfg_json.hide_private;
}}
class="btn btn-sm variant-ghost-secondary hover:variant-filled-secondary transition *:hover:inline"
title="Toggle visibility of private entries"
>
{#if $journals_slct.tmp_journal_obj.cfg_json.hide_private}
<!-- <EyeOff strokeWidth="1" color="red" /> -->
<ToggleLeft strokeWidth="1" color="red" class="mx-1" />
<Fingerprint strokeWidth="1" color="gray" class="mx-1" />
<span class="hidden">
Hiding
</span>
{:else}
<!-- <Eye strokeWidth="2.5" color="green" /> -->
<ToggleRight strokeWidth="2.5" color="green" class="mx-1" />
<Fingerprint strokeWidth="2.5" color="green" class="mx-1" />
<span class="hidden">
Showing
</span>
{/if}
<span class="hidden">
Private Entries
</span>
</button>
<button
type="button"
onclick={() => {
$journals_slct.tmp_journal_obj.cfg_json.hide_personal = !$journals_slct.tmp_journal_obj.cfg_json.hide_personal;
}}
class="btn btn-sm variant-ghost-secondary hover:variant-filled-secondary transition *:hover:inline"
title="Toggle visibility of personal entries"
>
{#if $journals_slct.tmp_journal_obj.cfg_json.hide_personal}
<!-- <EyeOff strokeWidth="1" color="red" /> -->
<ToggleLeft strokeWidth="1" color="red" class="mx-1" />
<BookHeart strokeWidth="1" color="gray" />
<span class="hidden">
Hiding
</span>
{:else}
<!-- <Eye strokeWidth="2.5" color="green" /> -->
<ToggleRight strokeWidth="2.5" color="green" class="mx-1" />
<BookHeart strokeWidth="2.5" color="green" />
<span class="hidden">
Showing
</span>
{/if}
<span class="hidden">
Personal Entries
</span>
</button>
<button
type="button"
onclick={() => {
$journals_slct.tmp_journal_obj.cfg_json.hide_professional = !$journals_slct.tmp_journal_obj.cfg_json.hide_professional;
}}
class="btn btn-sm variant-ghost-secondary hover:variant-filled-secondary transition *:hover:inline"
title="Toggle visibility of professional entries"
>
{#if $journals_slct.tmp_journal_obj.cfg_json.hide_professional}
<!-- <EyeOff strokeWidth="1" color="red" /> -->
<ToggleLeft strokeWidth="1" color="red" class="mx-1" />
<BriefcaseBusiness strokeWidth="1" color="gray" />
<span class="hidden">
Hiding
</span>
{:else}
<!-- <Eye strokeWidth="2.5" color="green" /> -->
<ToggleRight strokeWidth="2.5" color="green" class="mx-1" />
<BriefcaseBusiness strokeWidth="2.5" color="green" />
<span class="hidden">
Showing
</span>
{/if}
<span class="hidden">
Professional Entries
</span>
</button>
<!-- JSON configuration editor for advanced users -->
<!-- textarea for json_cfg editing -->
</div>

View File

@@ -156,7 +156,7 @@ let lq__journal_entry_obj = $derived(liveQuery(async () => {
{/if}
<span class="text-sm text-gray-500">
Edit Journal:
Edit Journal Entry:
</span>
{$lq__journal_entry_obj?.name}
</h3>

View File

@@ -3,15 +3,17 @@ let log_lvl: number = 0;
// *** Import Svelte specific
import { goto, invalidate, pushState, replaceState } from '$app/navigation';
import { Modal } from 'flowbite-svelte';
import {
CalendarClock, CodeXml, Copy,
CalendarClock, Check, CodeXml, Copy,
Eye, EyeOff,
Flag, FlagOff,
ListPlus,
NotebookPen, NotebookText, NotepadTextDashed,
RemoveFormatting,
Shapes, Siren,
Tags, TypeOutline
Tags, TypeOutline,
X
} from '@lucide/svelte';
@@ -34,6 +36,65 @@ let ae_promises: key_val = $state({});
// let ae_triggers: key_val = {};
let tmp_entry_obj: key_val = $state({});
let tmp_entry_obj_append_timestamp_header: Boolean = $state(false);
let tmp_entry_obj_append_text_header: String = $state('');
let tmp_entry_obj_append_text: String = $state('');
let tmp_entry_obj_changed: Boolean = $state(false);
$effect(() => {
if (tmp_entry_obj_append_text_header.length || tmp_entry_obj_append_text) {
tmp_entry_obj_changed = true;
} else {
tmp_entry_obj_changed = false;
}
});
// async function update_journal_entry(journal_entry_id) {
// if (!$ae_loc.trusted_access) {
// alert('You do not have permission to update this journal entry.');
// return;
// }
// let data_kv = {
// alert: tmp_entry_obj?.alert,
// personal: tmp_entry_obj?.personal,
// private: tmp_entry_obj?.private,
// professional: tmp_entry_obj?.professional,
// public: tmp_entry_obj?.public,
// template: tmp_entry_obj?.template,
// hide: tmp_entry_obj?.hide,
// priority: tmp_entry_obj?.priority,
// enable: tmp_entry_obj?.enable,
// // alert_msg: $lq__journal_entry_obj?.alert_msg ? false : true
// alert_msg: tmp_entry_obj?.alert_msg,
// category_code: tmp_entry_obj?.category_code,
// content: tmp_entry_obj?.content,
// group: tmp_entry_obj?.group,
// name: tmp_entry_obj?.name,
// tags: tmp_entry_obj?.tags,
// };
// // Call API to save the content
// try {
// await journals_func.update_ae_obj__journal_entry({
// api_cfg: $ae_api,
// journal_entry_id: journal_entry_id,
// data_kv: data_kv,
// log_lvl: 0,
// });
// // updated_obj = true;
// // updated_idb = false;
// console.log('Journal entry updated successfully!');
// } catch (error) {
// console.error('Error updating journal entry:', error);
// alert('Failed to update journal entry.');
// }
// }
</script>
@@ -259,7 +320,7 @@ let tmp_entry_obj: key_val = $state({});
<a
href="/journals/{journals_journal_entry_obj?.journal_id}/entry/{journals_journal_entry_obj?.journal_entry_id}"
class="btn btn-secondary variant-ghost-primary hover:variant-filled-primary transition"
class="btn variant-ghost-primary hover:variant-filled-primary transition"
title={`View ID: ${journals_journal_entry_obj?.id}\n${journals_journal_entry_obj?.name ?? ae_util.iso_datetime_formatter(journals_journal_entry_obj.created_on, 'datetime_iso_12_no_seconds')}`}
>
<NotebookPen class="mx-1 inline-block"/>
@@ -268,23 +329,44 @@ let tmp_entry_obj: key_val = $state({});
</span>
</a>
<!-- Button to show a modal that will allow for a quick append to Journal Entry option. -->
<button
type="button"
onclick={() => {
// if ($journals_sess.show__modal_append__journal_entry_id) {
// // $journals_sess.show__modal_append__journal_entry_id = null;
// $journals_sess.show__modal_append__journal_entry_id = journals_journal_entry_obj?.id;
// tmp_entry_obj = journals_journal_entry_obj;
// } else {
// $journals_sess.show__modal_append__journal_entry_id = journals_journal_entry_obj?.id;
// tmp_entry_obj = journals_journal_entry_obj;
// }
$journals_sess.show__modal_append__journal_entry_id = journals_journal_entry_obj?.id;
tmp_entry_obj = journals_journal_entry_obj;
}}
class="btn btn-icon btn-sm variant-ghost-surface hover:variant-filled-secondary transition"
>
<ListPlus />
<!-- Append -->
</button>
</div>
</header>
{#if journals_journal_entry_obj.content}
<!-- hover:border-gray-500 dark:hover:border-gray-500 -->
<div
class:hidden={journals_journal_entry_obj.hide}
class="
journal__content
class:hidden={journals_journal_entry_obj.hide || (journals_journal_entry_obj.private && $journals_slct.journal_obj?.cfg_json.hide_private) || (journals_journal_entry_obj.personal && $journals_slct.journal_obj?.cfg_json.hide_personal) || (journals_journal_entry_obj.professional && $journals_slct.journal_obj?.cfg_json.hide_professional) }
class="journal__content
w-full p-1
bg-slate-100 text-gray-900
dark:bg-slate-900 dark:text-gray-100
shadow-lg rounded-lg
border border-gray-200 dark:border-gray-700
hover:border-gray-500 dark:hover:border-gray-500
text-wrap text-sm font-mono whitespace-pre-wrap
delay-1000 duration-300 hover:delay-500 hover:duration-300 transition-all hover:transition-all ease-in-out
hover:z-10 hover:h-auto hover:max-h-full
hover:bg-blue-100 hover:border-blue-500 dark:hover:border-blue-500
{$journals_slct.journal_obj.cfg_json.entry_li_max_height ? `${$journals_slct.journal_obj.cfg_json.entry_li_max_height} overflow-scroll` : ''}
"
>
@@ -440,7 +522,171 @@ let tmp_entry_obj: key_val = $state({});
{/each}
<!-- </div> -->
<!-- Modal for quick append to Journal Entry -->
<!-- This should only have a textarea, Save button, and Cancel button. -->
{#if $journals_sess.show__modal_append__journal_entry_id}
<Modal
title="Append to Journal Entry {tmp_entry_obj?.name ?? 'No Journal Entry'} ({tmp_entry_obj?.journal_entry_id})"
bind:open={$journals_sess.show__modal_append__journal_entry_id}
autoclose={false}
placement="top-center"
size="xl"
class="top-center bg-white dark:bg-gray-800 text-gray-800 dark:text-gray-200 rounded-lg border-gray-200 dark:border-gray-700 divide-gray-200 dark:divide-gray-700 shadow-md relative flex flex-col mx-auto w-full divide-y"
>
<div class="modal">
<div class="modal-box">
<!-- <h3 class="font-bold text-lg">Edit Journal</h3> -->
<div class="py-4">
<!-- Checkbox for using the timestamp as the Markdown header. This will be pre-pended to any text header given, if any. -->
<div>
<input
type="checkbox"
id="append_timestamp_header"
bind:checked={tmp_entry_obj_append_timestamp_header}
class:border-orange-200={$ae_loc.edit_mode}
class:hover:border-orange-500={$ae_loc.edit_mode}
class="
p-2
bg-slate-100 text-gray-900
dark:bg-slate-900 dark:text-gray-100
shadow-lg rounded-lg
border border-gray-200 dark:border-gray-700
hover:border-gray-500 dark:hover:border-gray-500
inline-block
"
/>
<label
for="append_timestamp_header"
class:border-orange-200={$ae_loc.edit_mode}
class:hover:border-orange-500={$ae_loc.edit_mode}
class="
p-2
bg-slate-100 text-gray-900
dark:bg-slate-900 dark:text-gray-100
shadow-lg rounded-lg
border border-gray-200 dark:border-gray-700
hover:border-gray-500 dark:hover:border-gray-500
inline-block
"
>
Use timestamp as Markdown header
</label>
</div>
<input
type="text"
placeholder="Markdown header for appended content"
bind:value={tmp_entry_obj_append_text_header}
onchange={() => {
// tmp_entry_obj_changed = true;
}}
class:border-orange-200={$ae_loc.edit_mode}
class:hover:border-orange-500={$ae_loc.edit_mode}
class="
flex-grow min-h-12 h-full w-full
p-2
bg-slate-100 text-gray-900
dark:bg-slate-900 dark:text-gray-100
shadow-lg rounded-lg
border border-gray-200 dark:border-gray-700
hover:border-gray-500 dark:hover:border-gray-500
"
/>
<textarea
bind:value={tmp_entry_obj_append_text}
onchange={() => {
// tmp_entry_obj_changed = true;
}}
class:border-orange-200={$ae_loc.edit_mode}
class:hover:border-orange-500={$ae_loc.edit_mode}
class="
flex-grow min-h-48 h-full w-full
p-2
bg-slate-100 text-gray-900
dark:bg-slate-900 dark:text-gray-100
shadow-lg rounded-lg
border border-gray-200 dark:border-gray-700
hover:border-gray-500 dark:hover:border-gray-500
"
placeholder="Append to journal entry content..."
></textarea>
</div>
<div class="modal-action">
<button
type="button"
disabled={!tmp_entry_obj_changed}
onclick={() => {
let new_content = tmp_entry_obj?.content + '\n\n';
console.log(tmp_entry_obj_append_text_header);
console.log(tmp_entry_obj_append_text);
if (tmp_entry_obj_append_timestamp_header && tmp_entry_obj_append_text_header) {
new_content = new_content + '# ' + ae_util.iso_datetime_formatter(new Date(), 'datetime_iso_12_no_seconds') + ' - ' + tmp_entry_obj_append_text_header.trim() + '\n';
} else if (tmp_entry_obj_append_timestamp_header) {
new_content = new_content + '# ' + ae_util.iso_datetime_formatter(new Date(), 'datetime_iso_12_no_seconds') + '\n';
} else if (tmp_entry_obj_append_text_header) {
new_content = new_content + '# ' + tmp_entry_obj_append_text_header.trim() + '\n';
}
// if (tmp_entry_obj_append_text_header) {
// new_content = new_content + '# ' + tmp_entry_obj_append_text_header.trim() + '\n';
// }
if (tmp_entry_obj_append_text) {
new_content = new_content + tmp_entry_obj_append_text.trim();
}
new_content = new_content.trim() + '\n';
let data_kv = {
content: new_content,
};
journals_func.update_ae_obj__journal_entry({
api_cfg: $ae_api,
journal_entry_id: tmp_entry_obj?.journal_entry_id,
data_kv: data_kv,
log_lvl: log_lvl,
}).then(() => {
// Optionally, you can provide feedback to the user
// alert('Journal entry updated successfully!');
}).catch((error) => {
console.error('Error updating journal entry:', error);
alert('Failed to update journal entry.');
});
}}
class:variant-filled-error={tmp_entry_obj_changed}
class="
btn btn-sm md:btn-md lg:btn-lg
min-w-72 w-full lg:min-w-96
max-w-96
hover:variant-outline-success
hover:variant-filled-success
"
>
<Check />
Update
</button>
<button
type="button"
onclick={$journals_sess.show__modal_append__journal_entry_id ?? false}
class="btn variant-ghost-surface hover:variant-filled-surface transition"
>
<X />
Cancel
</button>
</div>
</div>
</div>
</Modal>
{/if}
{:else}
<p>No journal entry available to show.</p>