diff --git a/src/routes/journals/+layout.svelte b/src/routes/journals/+layout.svelte index ac919490..ecee7b53 100644 --- a/src/routes/journals/+layout.svelte +++ b/src/routes/journals/+layout.svelte @@ -1,86 +1,95 @@ @@ -97,15 +106,14 @@ class:iframe={$ae_loc?.iframe} class=" ae_journals - h-full max-h-full max-w-7xl + m-auto flex h-full + max-h-full + max-w-7xl flex-col gap-1 overflow-auto - flex flex-col gap-1 - m-auto - bg-gray-50 dark:bg-gray-900 - text-gray-800 dark:text-gray-200 - " - > + bg-gray-50 text-gray-800 + dark:bg-gray-900 dark:text-gray-200 + "> 250} class=" submenu - z-20 - hover:opacity-100 - absolute top-0 left-0 right-0 - w-full max-w-7xl - min-h-12 - p-1 px-2 pb-2 m-auto + absolute + top-0 + right-0 left-0 z-20 m-auto + flex min-h-12 + w-full + max-w-7xl flex-row flex-wrap items-center - flex flex-row flex-wrap - items-center justify-around sm:justify-between - gap-1 + justify-around gap-1 rounded-b-lg + border-b-2 bg-gray-200 p-1 + px-2 - border-b-2 rounded-b-lg + pb-2 transition-all - bg-gray-200 dark:bg-gray-800 + duration-1000 hover:opacity-100 - transition-all duration-1000 - " - > + sm:justify-between dark:bg-gray-800 + "> + class="mx-1 inline-block text-gray-500" /> Æ Journals + class="btn btn-sm preset-tonal-surface border-surface-500 hover:preset-filled-success-500 border"> Home @@ -213,9 +218,8 @@ // window.location.reload(true); // true only works with Firefox // alert('Local and Session Storage cleared and Indexed DBs deleted. You will probably want to refresh the page.'); }} - class="btn btn-sm preset-tonal-surface border border-surface-500 hover:preset-filled-warning-500" - title="Clear App Data & Settings: Clear IndexedDB and reload. If in edit mode localStorage and sessionStorage will also be cleared." - > + class="btn btn-sm preset-tonal-surface border-surface-500 hover:preset-filled-warning-500 border" + title="Clear App Data & Settings: Clear IndexedDB and reload. If in edit mode localStorage and sessionStorage will also be cleared."> @@ -230,8 +234,7 @@ show_btn_class="btn-info" additional_kv={{ test: true - }} - > + }}> @@ -244,23 +247,21 @@ class=" main_content grow - px-1 md:px-2 - pb-48 - " - > + px-1 pb-48 + md:px-2 + "> {@render children?.()} + flex-col items-end justify-end gap-1 hover:opacity-100 + "> + title="Scroll to top"> Scroll to Top @@ -321,8 +321,7 @@ window.parent.postMessage({ scroll_to: xScroll }, '*'); }} - title="Scroll to right" - > + title="Scroll to right"> - + + class="text-surface-900 dark:text-surface-100 text-3xl font-black tracking-tight sm:text-4xl md:text-5xl"> Journals @@ -105,7 +110,9 @@ {#if $ae_loc.person.given_name || $ae_loc.person.family_name} - {[$ae_loc.person.given_name, $ae_loc.person.family_name].filter(Boolean).join(' ')} + {[$ae_loc.person.given_name, $ae_loc.person.family_name] + .filter(Boolean) + .join(' ')} {/if} @@ -113,19 +120,17 @@ - + + class="from-primary-500 to-secondary-500 absolute -inset-1 rounded-2xl bg-linear-to-r opacity-25 blur transition duration-1000 group-hover:opacity-60 group-hover:duration-200 dark:opacity-40 dark:group-hover:opacity-70"> + + class="border-surface-500/10 bg-surface-50 dark:bg-surface-900 relative overflow-hidden rounded-xl border shadow-2xl" /> + class="mt-2 flex items-center justify-center gap-2 text-xs font-bold tracking-widest uppercase opacity-50"> Fast Input Mode Active @@ -134,33 +139,29 @@ {#if $ae_loc.edit_mode} + class="border-surface-500/10 flex w-full flex-row flex-wrap items-center justify-center gap-3 border-y py-4"> - ($journals_sess.show__modal_new__journal_obj = true)} - > + ($journals_sess.show__modal_new__journal_obj = true)}> New Journal (show_import_modal = true)} - > + class="btn preset-tonal-surface shadow-lg transition-transform hover:scale-105" + onclick={() => (show_import_modal = true)}> Import - ($journals_sess.show__modal__journals_config = true)} - > + ($journals_sess.show__modal__journals_config = true)}> Config @@ -168,11 +169,10 @@ {/if} - + {#if $lq__journal_obj_li === undefined} + class="flex flex-col items-center justify-center gap-4 p-20 opacity-50"> Accessing Brain... @@ -180,11 +180,10 @@ {:else} + class="bg-surface-500/5 border-surface-500/20 max-w-md rounded-3xl border-2 border-dashed p-12 text-center"> - No Journals Found - + No Journals Found + You haven't created any journals yet. Start by creating one to begin your documentation journey. @@ -192,8 +191,7 @@ type="button" class="btn preset-filled-primary" onclick={() => - ($journals_sess.show__modal_new__journal_obj = true)} - > + ($journals_sess.show__modal_new__journal_obj = true)}> Create Your First Journal @@ -208,32 +206,27 @@ bind:open={$journals_sess.show__modal_new__journal_obj} autoclose={false} size="md" - class="bg-white dark:bg-surface-900 shadow-2xl rounded-2xl" - > - + class="dark:bg-surface-900 rounded-2xl bg-white shadow-2xl"> + Journal Name + >Journal Name + class="input" /> Type Code + >Type Code + class="input" /> ($journals_sess.show__modal_new__journal_obj = false)} - >Cancel + >Cancel Create Journal + onclick={create_journal}>Create Journal @@ -255,12 +246,10 @@ {#if $journals_sess.show__modal__journals_config} + show={$journals_sess.show__modal__journals_config} /> {/if} (show_import_modal = false)} - on_import_complete={() => {}} -/> + on_import_complete={() => {}} /> diff --git a/src/routes/journals/[journal_id]/+layout.svelte b/src/routes/journals/[journal_id]/+layout.svelte index 7e7d86c4..8ce3fef0 100644 --- a/src/routes/journals/[journal_id]/+layout.svelte +++ b/src/routes/journals/[journal_id]/+layout.svelte @@ -1,83 +1,83 @@ @@ -85,29 +85,27 @@ class=" ae_journals__journal mx-auto - flex flex-col grow gap-1 - items-center - min-h-full - max-h-max + flex max-h-max min-h-full max-w-max min-w-full - max-w-max + grow + flex-col + items-center + gap-1 space-y-2 - " -> + "> + hover:bg-slate-100 hover:dark:bg-slate-700 + "> +Middle-click to open in new tab`}> {#if show_menu__all_journals} @@ -152,16 +149,15 @@ Middle-click to open in new tab`} + class:hidden={!show_menu__all_journals}> + title="View all journals for this account: {$ae_loc.account_name}"> @@ -195,12 +190,11 @@ Middle-click to open in new tab`} }} class=" form-select + border-neutral-400-600 w-full + border p-1 text-sm - border border-neutral-400-600 - p-1 - " - > + "> {Object.keys($journals_loc.entry_view_history_kv) .length}× Recent Entries... @@ -228,8 +222,7 @@ Middle-click to open in new tab`} hover:preset-filled-tertiary-300-700 transition-all " - title="View all journal entries for this journal: {$lq__journal_obj?.name}" - > + title="View all journal entries for this journal: {$lq__journal_obj?.name}"> @@ -315,8 +308,7 @@ Middle-click to open in new tab`} hover:preset-filled-tertiary-300-700 transition-all " - title="Create a new journal entry for this journal: {$lq__journal_obj?.name}" - > + title="Create a new journal entry for this journal: {$lq__journal_obj?.name}"> New Entry diff --git a/src/routes/journals/[journal_id]/+page.svelte b/src/routes/journals/[journal_id]/+page.svelte index fae4b122..569a4602 100644 --- a/src/routes/journals/[journal_id]/+page.svelte +++ b/src/routes/journals/[journal_id]/+page.svelte @@ -1,295 +1,291 @@ @@ -300,9 +296,8 @@ {#if $lq__journal_obj === undefined} - + class="flex flex-col items-center justify-center p-20 text-center opacity-50"> + Loading Journal... {:else if $ae_loc.person_id == $lq__journal_obj?.person_id} @@ -310,32 +305,27 @@ {lq__journal_obj} {lq__journal_entry_obj_li} on_show_export={() => (show_export_modal = true)} - on_show_import={() => (show_import_modal = true)} - /> + on_show_import={() => (show_import_modal = true)} /> + {log_lvl} /> (show_export_modal = false)} - /> + on_close={() => (show_export_modal = false)} /> (show_import_modal = false)} - on_import_complete={handle_import_complete} - /> + on_import_complete={handle_import_complete} /> {:else} + class="main_content flex grow flex-col items-center gap-1 px-1 pb-28 md:px-2"> You must be logged in as the owner to view this Journal. diff --git a/src/routes/journals/[journal_id]/entry/[journal_entry_id]/+page.svelte b/src/routes/journals/[journal_id]/entry/[journal_entry_id]/+page.svelte index 6601c77a..17107b4a 100644 --- a/src/routes/journals/[journal_id]/entry/[journal_entry_id]/+page.svelte +++ b/src/routes/journals/[journal_id]/entry/[journal_entry_id]/+page.svelte @@ -1,264 +1,256 @@ (show_export_modal = true)} - /> + on_show_export={() => (show_export_modal = true)} /> @@ -297,12 +287,10 @@ bind:open={show_export_modal} entries={$lq__journal_entry_obj ? [$lq__journal_entry_obj] : []} journal={$lq__journal_obj} - on_close={() => (show_export_modal = false)} - /> + on_close={() => (show_export_modal = false)} /> {:else} + class="main_content flex grow flex-col items-center gap-1 px-1 pb-28 md:px-2"> You must be logged in as the owner to view this Journal Entry. diff --git a/src/routes/journals/ae_comp__journal_entry_ai_tools.svelte b/src/routes/journals/ae_comp__journal_entry_ai_tools.svelte index 1fac73bf..7baf9f76 100644 --- a/src/routes/journals/ae_comp__journal_entry_ai_tools.svelte +++ b/src/routes/journals/ae_comp__journal_entry_ai_tools.svelte @@ -1,24 +1,19 @@ @@ -29,6 +24,5 @@ summary = newSummary; on_save(); }} - {log_lvl} - /> + {log_lvl} /> diff --git a/src/routes/journals/ae_comp__journal_entry_editor.svelte b/src/routes/journals/ae_comp__journal_entry_editor.svelte index 4fdc203e..b53ee883 100644 --- a/src/routes/journals/ae_comp__journal_entry_editor.svelte +++ b/src/routes/journals/ae_comp__journal_entry_editor.svelte @@ -1,51 +1,50 @@ + class="journal-entry-editor-wrapper flex w-full grow flex-col items-center"> {#if !is_editing} - + {@html tmp_entry_obj?.content_md_html || ''} {:else} @@ -53,10 +52,9 @@ {#if !tmp_entry_obj?.content && tmp_entry_obj?.content_encrypted} + class="bg-error-100 dark:bg-error-900/30 text-error-900 dark:text-error-100 border-error-500 flex w-full max-w-6xl flex-col gap-4 rounded-lg border p-4"> - + Decryption Required @@ -65,16 +63,15 @@ {#if tmp_entry_obj?.content === false} + class="text-error-500 text-xs font-bold tracking-widest uppercase"> Decryption failed. Incorrect passcode. {/if} {#if $ae_loc.edit_mode && on_force_reset} - - + + Passcode lost? You can force a reset to plain text, but all currently encrypted data will be permanently deleted. @@ -82,8 +79,7 @@ + onclick={on_force_reset}> Force Reset to Plain Text @@ -98,14 +94,12 @@ bind:editor_view theme_mode={$ae_loc.theme_mode} placeholder="Write using Markdown..." - class_li="p-2 preset-outlined-warning-300-700 shadow-lg rounded-lg w-full max-w-6xl bg-surface-50 dark:bg-surface-800" - /> + class_li="p-2 preset-outlined-warning-300-700 shadow-lg rounded-lg w-full max-w-6xl bg-surface-50 dark:bg-surface-800" /> {:else} + class="textarea h-[500px] w-full max-w-6xl grow rounded-lg border-orange-500/30 p-4 font-mono break-words whitespace-pre-wrap shadow-lg" + placeholder="Edit content..."> {/if} @@ -113,9 +107,8 @@ type="button" onclick={on_save} disabled={!has_changed} - class="btn btn-sm md:btn-md lg:btn-lg fixed top-72 right-6 min-w-32 preset-filled-success shadow-xl z-20 transition-all" - class:hidden={!has_changed} - > + class="btn btn-sm md:btn-md lg:btn-lg preset-filled-success fixed top-72 right-6 z-20 min-w-32 shadow-xl transition-all" + class:hidden={!has_changed}> Save @@ -124,16 +117,14 @@ type="button" onclick={on_save} disabled={!has_changed} - class="btn preset-tonal-warning hover:preset-filled-warning-500 w-full max-w-96 mt-4" - class:invisible={!has_changed} - > + class="btn preset-tonal-warning hover:preset-filled-warning-500 mt-4 w-full max-w-96" + class:invisible={!has_changed}> Save Changes {#if updated_idb} + class="text-error-500 mt-2 animate-pulse text-xs font-bold tracking-widest uppercase"> IDB object updated since last load! {/if} diff --git a/src/routes/journals/ae_comp__journal_entry_header.svelte b/src/routes/journals/ae_comp__journal_entry_header.svelte index 705850ee..d8bca437 100644 --- a/src/routes/journals/ae_comp__journal_entry_header.svelte +++ b/src/routes/journals/ae_comp__journal_entry_header.svelte @@ -1,75 +1,85 @@ - + class="flex w-full flex-col items-center justify-between gap-4 rounded-xl + border border-gray-200 + bg-gray-50 p-3 shadow-sm + md:flex-row dark:border-gray-700 dark:bg-gray-800"> + + title="Back to Journal"> - + + : 'preset-tonal-surface'}"> {#if $journals_loc.entry.edit_kv[entry.journal_entry_id] === 'current'} {#if has_changed}{:else}{/if} + size="1.2em" />{/if} {:else} {/if} @@ -92,12 +100,11 @@ + onchange={on_save} /> {:else} - + {entry.name || ae_util.iso_datetime_formatter( entry.created_on, @@ -108,12 +115,11 @@ - + {#if $journals_loc.entry.edit_kv[entry.journal_entry_id] === 'current'} + class="border-surface-500/20 mr-1 flex items-center gap-1 border-r px-2"> + title="Toggle Auto Save"> {#if $journals_loc.entry.auto_save} {#if save_status === 'saving'} + class="text-primary-500 animate-spin" /> {:else if save_status === 'saved'} + class="text-success-500" /> {:else}{/if} {/if} @@ -145,25 +148,22 @@ + title={is_decrypted ? 'Lock Content' : 'Decrypt Content'}> {#if is_decrypted}{:else}{/if} + size="1.2em" />{:else}{/if} {/if} - + + onclick={on_show_config}> Config @@ -172,8 +172,7 @@ + onclick={on_save}> Save {/if} diff --git a/src/routes/journals/ae_comp__journal_entry_metadata.svelte b/src/routes/journals/ae_comp__journal_entry_metadata.svelte index b24eacc3..bbf148ca 100644 --- a/src/routes/journals/ae_comp__journal_entry_metadata.svelte +++ b/src/routes/journals/ae_comp__journal_entry_metadata.svelte @@ -1,25 +1,24 @@ + class="text-surface-500 flex flex-col items-center justify-between gap-2 px-1 text-xs sm:flex-row"> Created: diff --git a/src/routes/journals/ae_comp__journal_entry_obj_file_li.svelte b/src/routes/journals/ae_comp__journal_entry_obj_file_li.svelte index 1cc2747a..e84c52fd 100644 --- a/src/routes/journals/ae_comp__journal_entry_obj_file_li.svelte +++ b/src/routes/journals/ae_comp__journal_entry_obj_file_li.svelte @@ -1,205 +1,206 @@ - + + class="border-surface-500/20 flex items-center justify-between border-b pb-2"> Attachments {#if unified_file_li.length} {unified_file_li.length} + >{unified_file_li.length} {/if} @@ -212,8 +213,7 @@ $ae_sess.files.add_to_use_files_method === 'upload' ? 'select' : 'upload'; - }} - > + }}> {$ae_sess.files.add_to_use_files_method === 'select' ? 'Switch to Upload' @@ -224,14 +224,13 @@ {#if unified_file_li.length} - + {#each unified_file_li as file (file.hosted_file_id ?? file.id)} {@const file_id = file.hosted_file_id || file.id || file.hosted_file_id} - + class="bg-surface-50-950 border-surface-500/10 group hover:border-primary-500 flex items-center justify-between rounded-xl border p-3 shadow-sm transition-all"> + + $ae_loc.edit_mode} /> - + {#if $ae_loc.edit_mode} handle_remove_file(file_id)} - title="Remove attachment" - > + title="Remove attachment"> {/if} @@ -262,8 +259,7 @@ {:else if !$ae_loc.edit_mode} + class="text-surface-500 bg-surface-500/5 rounded-xl p-4 text-center text-sm italic"> No files attached to this entry. {/if} @@ -271,8 +267,7 @@ {#if $ae_loc.edit_mode} + class="bg-surface-500/5 border-surface-500/20 mt-4 rounded-2xl border-2 border-dashed p-4"> {#if $ae_sess.files.add_to_use_files_method === 'upload'} + class_li="!max-w-none"> {#snippet label()} + class="bg-primary-500/10 text-primary-500 rounded-full p-3"> @@ -302,7 +295,7 @@ {:else} - + Select from existing hosted files: + bind:slct_hosted_file_obj /> {/if} diff --git a/src/routes/journals/ae_comp__journal_entry_obj_id_view.svelte b/src/routes/journals/ae_comp__journal_entry_obj_id_view.svelte index cfe5ea94..53392db0 100644 --- a/src/routes/journals/ae_comp__journal_entry_obj_id_view.svelte +++ b/src/routes/journals/ae_comp__journal_entry_obj_id_view.svelte @@ -1,548 +1,522 @@ - + - - {#if $lq__journal_entry_obj && $lq__journal_obj} - update_journal_entry()} - on_decrypt={handle_content_decryption} - on_show_config={() => (show_config_modal = true)} - {save_status} - {log_lvl} - /> + class="from-primary-500/50 to-secondary-500/50 pointer-events-none absolute -inset-1 + rounded-2xl bg-linear-to-r opacity-5 blur + transition duration-700 + group-hover/entry-view:opacity-15 dark:opacity-10 dark:group-hover/entry-view:opacity-20"> + + + {#if $lq__journal_entry_obj && $lq__journal_obj} + update_journal_entry()} + on_decrypt={handle_content_decryption} + on_show_config={() => (show_config_modal = true)} + {save_status} + {log_lvl} /> - {#if decryption_error} - + {#if decryption_error} - - {decryption_error} + class="bg-error-500/20 border-error-500 z-50 flex w-full animate-bounce items-center justify-between rounded-lg border-2 p-4 shadow-2xl"> + + + {decryption_error} + + (decryption_error = null)}> + Dismiss + - (decryption_error = null)} - > - Dismiss - - - {/if} + {/if} - - - - + + + update_journal_entry()} + {log_lvl} /> + + + update_journal_entry()} - {log_lvl} - /> - + on_force_reset={handle_force_reset} /> + - + + + + (show_append_modal = false)} + on_update={() => { + show_append_modal = false; + }} + {log_lvl} /> + + update_journal_entry()} on_force_reset={handle_force_reset} - /> - - - - - - - (show_append_modal = false)} - on_update={() => { - show_append_modal = false; - }} - {log_lvl} - /> - - update_journal_entry()} - on_force_reset={handle_force_reset} - {on_show_export} - on_append={() => { - modal_mode = 'append'; - show_append_modal = true; - }} - on_prepend={() => { - modal_mode = 'prepend'; - show_append_modal = true; - }} - {log_lvl} - /> - {:else} - - - Loading Journal Entry... - - {/if} - + {on_show_export} + on_append={() => { + modal_mode = 'append'; + show_append_modal = true; + }} + on_prepend={() => { + modal_mode = 'prepend'; + show_append_modal = true; + }} + {log_lvl} /> + {:else} + + + Loading Journal Entry... + + {/if} + diff --git a/src/routes/journals/ae_comp__journal_entry_obj_li.svelte b/src/routes/journals/ae_comp__journal_entry_obj_li.svelte index 393b2737..a1c88985 100644 --- a/src/routes/journals/ae_comp__journal_entry_obj_li.svelte +++ b/src/routes/journals/ae_comp__journal_entry_obj_li.svelte @@ -1,746 +1,738 @@ - + - - {#if visible_journal_entry_obj_li === null} - - - - Loading visible entries... - - {:else if visible_journal_entry_obj_li.length > 0} - {#if show_found_header} - - - - Found: - - - {visible_journal_entry_obj_li.length}× - - - - {/if} - - {#each visible_journal_entry_obj_li as journals_journal_entry_obj, index (journals_journal_entry_obj.journal_entry_id)} + class="from-primary-500/50 to-secondary-500/50 pointer-events-none absolute -inset-1 + rounded-2xl bg-linear-to-r opacity-5 blur + transition duration-700 + group-hover/entries:opacity-15 dark:opacity-10 dark:group-hover/entries:opacity-20"> + + + {#if visible_journal_entry_obj_li === null} + - - - - {#if journals_journal_entry_obj.alert} - - {/if} - - {#if journals_journal_entry_obj.priority} - - {/if} - - {#if journals_journal_entry_obj.group} - - Group: - - {journals_journal_entry_obj.group} - - {/if} + class="flex flex-col items-center justify-center p-10 opacity-50"> + + Loading visible entries... + + {:else if visible_journal_entry_obj_li.length > 0} + {#if show_found_header} + + + + Found: - - - {#if journals_journal_entry_obj.template} - - - {@html journals_journal_entry_obj.name ?? - '-- no name --'} - {:else if journals_journal_entry_obj.name} - - {@html journals_journal_entry_obj.name} - {:else} - - {ae_util.iso_datetime_formatter( - journals_journal_entry_obj.created_on, - 'datetime_iso_12_no_seconds' - )} - {/if} - - - {#if !journals_journal_entry_obj.private} - - { - let tmp_entry_obj = - journals_journal_entry_obj; + class="badge preset-tonal-success px-3 py-1 text-lg font-bold"> + {visible_journal_entry_obj_li.length}× + + + + {/if} - navigator.clipboard - .writeText(tmp_entry_obj.content) - .then(() => { - alert( - 'Markdown content copied to clipboard!' - ); - }) - .catch((error) => { - console.error( - 'Failed to copy content:', - error - ); - alert( - 'Failed to copy content.' - ); - }); - }} - class:hidden={$lq__journal_obj?.cfg_json - ?.hide_copy_plain_md} - class="btn btn-sm p-1 preset-tonal-surface hover:preset-filled-secondary-500 *:hover:inline text-xs lg:text-sm" - title="Copy the markdown content" - > - - - Copy Plaintext Markdown + {#each visible_journal_entry_obj_li as journals_journal_entry_obj, index (journals_journal_entry_obj.journal_entry_id)} + + + + + {#if journals_journal_entry_obj.alert} + + {/if} + + {#if journals_journal_entry_obj.priority} + + {/if} + + {#if journals_journal_entry_obj.group} + + Group: + + {journals_journal_entry_obj.group} - + {/if} + - - { - let htmlContent = - journals_journal_entry_obj.content_md_html || - ''; + + {#if journals_journal_entry_obj.template} + - navigator.clipboard - .writeText(htmlContent) - .then(() => { - alert( - 'Rendered HTML content copied to clipboard!' - ); - }) - .catch((error) => { - console.error( - 'Failed to copy HTML content:', - error - ); - alert( - 'Failed to copy HTML content.' - ); - }); - }} - class:hidden={journals_journal_entry_obj.template || - $lq__journal_obj?.cfg_json - ?.hide_copy_html} - class="btn btn-sm p-1 preset-tonal-surface hover:preset-filled-secondary-500 *:hover:inline lg:text-xs" - title="Copy the rendered HTML content" - > - - - Copy HTML Markup - - + {@html journals_journal_entry_obj.name ?? + '-- no name --'} + {:else if journals_journal_entry_obj.name} + + {@html journals_journal_entry_obj.name} + {:else} + + {ae_util.iso_datetime_formatter( + journals_journal_entry_obj.created_on, + 'datetime_iso_12_no_seconds' + )} + {/if} + - - { - const element = document.getElementById( - `rendered_journal_entry_content_${journals_journal_entry_obj.journal_entry_id}` - ); - if (!element) { - console.error( - 'Element not found: rendered_journal_entry_content' - ); - alert( - 'Failed to copy rich content.' - ); - return; - } + + {#if !journals_journal_entry_obj.private} + + { + let tmp_entry_obj = + journals_journal_entry_obj; - try { - const htmlContent = - element.innerHTML; - await navigator.clipboard.write([ - new ClipboardItem({ - 'text/html': new Blob( - [htmlContent], - { - type: 'text/html' - } - ) - }) - ]); - - alert( - 'Rendered rich content copied to clipboard!' - ); - } catch (error) { - console.error( - 'Failed to copy rich content:', - error - ); - alert( - 'Failed to copy rich content.' - ); - } - }} - class:hidden={journals_journal_entry_obj.template || - $lq__journal_obj?.cfg_json - ?.hide_copy_rich} - class="btn btn-sm p-1 preset-tonal-surface hover:preset-filled-secondary-500 *:hover:inline lg:text-xs" - title="Copy the rich text (rendered HTML) content" - > - - Copy Rich Text - - - - { - let data_kv = { - code: journals_journal_entry_obj.code, - category_code: - journals_journal_entry_obj.category_code, - name: journals_journal_entry_obj.name, - short_name: - journals_journal_entry_obj.short_name, - content: - journals_journal_entry_obj.content, - description: - journals_journal_entry_obj.description, - tags: journals_journal_entry_obj.tags - }; - - journals_func - .create_ae_obj__journal_entry({ - api_cfg: $ae_api, - journal_id: - journals_journal_entry_obj.journal_id, - data_kv: data_kv, - log_lvl: log_lvl - }) - .then((result) => { - if ( - result?.journal_id && - result?.journal_entry_id - ) { + navigator.clipboard + .writeText( + tmp_entry_obj.content + ) + .then(() => { alert( - 'Journal entry cloned successfully!' + 'Markdown content copied to clipboard!' ); - goto( - `/journals/${result.journal_id}/entry/${result.journal_entry_id}` + }) + .catch((error) => { + console.error( + 'Failed to copy content:', + error ); - } - }) - .catch((error) => { + alert( + 'Failed to copy content.' + ); + }); + }} + class:hidden={$lq__journal_obj?.cfg_json + ?.hide_copy_plain_md} + class="btn btn-sm preset-tonal-surface hover:preset-filled-secondary-500 p-1 text-xs *:hover:inline lg:text-sm" + title="Copy the markdown content"> + + + Copy Plaintext Markdown + + + + + { + let htmlContent = + journals_journal_entry_obj.content_md_html || + ''; + + navigator.clipboard + .writeText(htmlContent) + .then(() => { + alert( + 'Rendered HTML content copied to clipboard!' + ); + }) + .catch((error) => { + console.error( + 'Failed to copy HTML content:', + error + ); + alert( + 'Failed to copy HTML content.' + ); + }); + }} + class:hidden={journals_journal_entry_obj.template || + $lq__journal_obj?.cfg_json + ?.hide_copy_html} + class="btn btn-sm preset-tonal-surface hover:preset-filled-secondary-500 p-1 *:hover:inline lg:text-xs" + title="Copy the rendered HTML content"> + + + Copy HTML Markup + + + + + { + const element = + document.getElementById( + `rendered_journal_entry_content_${journals_journal_entry_obj.journal_entry_id}` + ); + if (!element) { console.error( - 'Error cloning journal entry:', + 'Element not found: rendered_journal_entry_content' + ); + alert( + 'Failed to copy rich content.' + ); + return; + } + + try { + const htmlContent = + element.innerHTML; + await navigator.clipboard.write( + [ + new ClipboardItem({ + 'text/html': + new Blob( + [ + htmlContent + ], + { + type: 'text/html' + } + ) + }) + ] + ); + + alert( + 'Rendered rich content copied to clipboard!' + ); + } catch (error) { + console.error( + 'Failed to copy rich content:', error ); alert( - 'Failed to clone journal entry.' + 'Failed to copy rich content.' ); - }); - }} - class:hidden={!journals_journal_entry_obj.template} - class="btn btn-sm p-1 preset-tonal-surface hover:preset-filled-secondary-500 *:hover:inline lg:text-xs" - title="Clone this journal entry" - > - - Clone - - {:else} - - Private + } + }} + class:hidden={journals_journal_entry_obj.template || + $lq__journal_obj?.cfg_json + ?.hide_copy_rich} + class="btn btn-sm preset-tonal-surface hover:preset-filled-secondary-500 p-1 *:hover:inline lg:text-xs" + title="Copy the rich text (rendered HTML) content"> + + Copy Rich Text + - + + { + let data_kv = { + code: journals_journal_entry_obj.code, + category_code: + journals_journal_entry_obj.category_code, + name: journals_journal_entry_obj.name, + short_name: + journals_journal_entry_obj.short_name, + content: + journals_journal_entry_obj.content, + description: + journals_journal_entry_obj.description, + tags: journals_journal_entry_obj.tags + }; + + journals_func + .create_ae_obj__journal_entry({ + api_cfg: $ae_api, + journal_id: + journals_journal_entry_obj.journal_id, + data_kv: data_kv, + log_lvl: log_lvl + }) + .then((result) => { + if ( + result?.journal_id && + result?.journal_entry_id + ) { + alert( + 'Journal entry cloned successfully!' + ); + goto( + `/journals/${result.journal_id}/entry/${result.journal_entry_id}` + ); + } + }) + .catch((error) => { + console.error( + 'Error cloning journal entry:', + error + ); + alert( + 'Failed to clone journal entry.' + ); + }); + }} + class:hidden={!journals_journal_entry_obj.template} + class="btn btn-sm preset-tonal-surface hover:preset-filled-secondary-500 p-1 *:hover:inline lg:text-xs" + title="Clone this journal entry"> + + Clone + + {:else} + + Private + + + { + let tmp_entry_obj = + journals_journal_entry_obj; + + navigator.clipboard + .writeText( + tmp_entry_obj.content_encrypted + ) + .then(() => { + alert( + 'Encrypted content copied to clipboard!' + ); + }) + .catch((error) => { + console.error( + 'Failed to copy content:', + error + ); + alert( + 'Failed to copy content.' + ); + }); + }} + class:hidden={$lq__journal_obj?.cfg_json + ?.hide_copy_encrypted} + class="btn btn-sm preset-tonal-surface hover:preset-filled-secondary-500 p-1 text-xs *:hover:inline lg:text-sm" + title="Copy the encrypted content"> + + + Copy Encrypted + + + {/if} + + + + + + + + Linked files: + + {journals_journal_entry_obj?.data_json + ?.hosted_file_kv + ? Object.keys( + journals_journal_entry_obj + ?.data_json?.hosted_file_kv + ).length + : 0}× + + + + + {#if journals_journal_entry_obj.tags && journals_journal_entry_obj.tags.length} + + + Tags: + + {#each journals_journal_entry_obj.tags.split(',') as tag (tag)} + + {tag.trim()} + + {/each} + + {/if} + + + {#if journals_journal_entry_obj.category_code} { - let tmp_entry_obj = - journals_journal_entry_obj; - - navigator.clipboard - .writeText( - tmp_entry_obj.content_encrypted - ) - .then(() => { - alert( - 'Encrypted content copied to clipboard!' - ); - }) - .catch((error) => { - console.error( - 'Failed to copy content:', - error - ); - alert( - 'Failed to copy content.' - ); - }); + if ( + $journals_loc.entry + .qry__category_code == + journals_journal_entry_obj.category_code + ) { + $journals_loc.entry.qry__category_code = + null; + } else { + $journals_loc.entry.qry__category_code = + journals_journal_entry_obj.category_code; + } + if ( + $journals_loc.entry + .search_version === undefined + ) + $journals_loc.entry.search_version = 0; + $journals_loc.entry.search_version++; }} - class:hidden={$lq__journal_obj?.cfg_json - ?.hide_copy_encrypted} - class="btn btn-sm p-1 preset-tonal-surface hover:preset-filled-secondary-500 *:hover:inline text-xs lg:text-sm" - title="Copy the encrypted content" - > - - Copy Encrypted + class:bg-green-100={$journals_loc.entry + .qry__category_code == + journals_journal_entry_obj.category_code} + class="btn btn-sm preset-outlined-secondary hover:preset-filled-secondary-500 px-2 py-1 transition" + title={`Filter by category: ${journals_journal_entry_obj.category_code}`}> + + {journals_journal_entry_obj.category_code ?? + '-- no category --'} {/if} - - - - - - - Linked files: - - {journals_journal_entry_obj?.data_json - ?.hosted_file_kv - ? Object.keys( - journals_journal_entry_obj?.data_json - ?.hosted_file_kv - ).length - : 0}× - - + + + View + - - {#if journals_journal_entry_obj.tags && journals_journal_entry_obj.tags.length} - - - Tags: - - {#each journals_journal_entry_obj.tags.split(',') as tag (tag)} - - {tag.trim()} - - {/each} - - {/if} - - - {#if journals_journal_entry_obj.category_code} + { - if ( - $journals_loc.entry - .qry__category_code == - journals_journal_entry_obj.category_code - ) { - $journals_loc.entry.qry__category_code = - null; - } else { - $journals_loc.entry.qry__category_code = - journals_journal_entry_obj.category_code; - } - if ( - $journals_loc.entry.search_version === - undefined - ) - $journals_loc.entry.search_version = 0; - $journals_loc.entry.search_version++; + $journals_sess.show__modal_append__journal_entry_id = + journals_journal_entry_obj?.id; + tmp_entry_obj = JSON.parse( + JSON.stringify( + journals_journal_entry_obj + ) + ); }} - class:bg-green-100={$journals_loc.entry - .qry__category_code == - journals_journal_entry_obj.category_code} - class="btn btn-sm preset-outlined-secondary hover:preset-filled-secondary-500 transition py-1 px-2" - title={`Filter by category: ${journals_journal_entry_obj.category_code}`} - > - - {journals_journal_entry_obj.category_code ?? - '-- no category --'} + class="btn btn-icon btn-sm preset-tonal-surface border-surface-500 hover:preset-filled-secondary-500 border transition" + title={$lq__journal_obj?.cfg_json + ?.entry_add_text == 'append' + ? 'Append to Journal Entry' + : 'Prepend to Journal Entry'}> + - {/if} + + - - - View - + {#if journals_journal_entry_obj.content} + + {@html journals_journal_entry_obj.content} + + + + {@html journals_journal_entry_obj?.content_md_html} + + {/if} + + + + Original date/time: + {#if journals_journal_entry_obj.original_datetime} + {ae_util.iso_datetime_formatter( + journals_journal_entry_obj.original_datetime, + 'datetime_12_long' + )} + {/if} + {#if journals_journal_entry_obj.original_timezone} + Timezone: + {journals_journal_entry_obj.original_timezone} + {/if} + + + + + + + Created: + {ae_util.iso_datetime_formatter( + journals_journal_entry_obj.created_on, + 'datetime_12_long' + )} + + + Last update: + {ae_util.iso_datetime_formatter( + journals_journal_entry_obj.updated_on, + 'datetime_12_long' + )} + + + + { - $journals_sess.show__modal_append__journal_entry_id = - journals_journal_entry_obj?.id; - tmp_entry_obj = JSON.parse( - JSON.stringify(journals_journal_entry_obj) - ); + let data_kv = { + hide: journals_journal_entry_obj?.hide + ? false + : true + }; + journals_func + .update_ae_obj__journal_entry({ + api_cfg: $ae_api, + journal_entry_id: + journals_journal_entry_obj.journal_entry_id, + data_kv: data_kv, + log_lvl: log_lvl + }) + .then(() => {}) + .catch((error) => { + console.error( + 'Error updating journal entry:', + error + ); + alert( + 'Failed to update journal entry.' + ); + }); }} - class="btn btn-icon btn-sm preset-tonal-surface border border-surface-500 hover:preset-filled-secondary-500 transition" - title={$lq__journal_obj?.cfg_json?.entry_add_text == - 'append' - ? 'Append to Journal Entry' - : 'Prepend to Journal Entry'} - > - + class:hidden={!$ae_loc.edit_mode} + class="btn btn-sm preset-tonal-surface hover:preset-filled-warning-500 px-2 py-1 transition" + title={`Set entry as ${journals_journal_entry_obj.hide ? 'visible' : 'hidden'}`}> + {#if journals_journal_entry_obj.hide} + + Hidden + {:else} + + Visible + {/if} - - + + + {/each} - {#if journals_journal_entry_obj.content} - - {@html journals_journal_entry_obj.content} - - - - {@html journals_journal_entry_obj?.content_md_html} - - {/if} - - - - Original date/time: - {#if journals_journal_entry_obj.original_datetime} - {ae_util.iso_datetime_formatter( - journals_journal_entry_obj.original_datetime, - 'datetime_12_long' - )} - {/if} - {#if journals_journal_entry_obj.original_timezone} - Timezone: - {journals_journal_entry_obj.original_timezone} - {/if} - - - - - - - Created: - {ae_util.iso_datetime_formatter( - journals_journal_entry_obj.created_on, - 'datetime_12_long' - )} - - - Last update: - {ae_util.iso_datetime_formatter( - journals_journal_entry_obj.updated_on, - 'datetime_12_long' - )} - - - - - { - let data_kv = { - hide: journals_journal_entry_obj?.hide - ? false - : true - }; - journals_func - .update_ae_obj__journal_entry({ - api_cfg: $ae_api, - journal_entry_id: - journals_journal_entry_obj.journal_entry_id, - data_kv: data_kv, - log_lvl: log_lvl - }) - .then(() => {}) - .catch((error) => { - console.error( - 'Error updating journal entry:', - error - ); - alert('Failed to update journal entry.'); - }); - }} - class:hidden={!$ae_loc.edit_mode} - class="btn btn-sm preset-tonal-surface hover:preset-filled-warning-500 transition py-1 px-2" - title={`Set entry as ${journals_journal_entry_obj.hide ? 'visible' : 'hidden'}`} - > - {#if journals_journal_entry_obj.hide} - - Hidden - {:else} - - Visible - {/if} - - + + {#if $journals_sess.show__modal_append__journal_entry_id} + + {/if} + {:else} + + + + No Journal Entry available to show. Please check the query + filters or create a new Entry. + - {/each} - - - {#if $journals_sess.show__modal_append__journal_entry_id} - {/if} - {:else} - - - - No Journal Entry available to show. Please check the query - filters or create a new Entry. - - - {/if} - + diff --git a/src/routes/journals/ae_comp__journal_entry_obj_li_wrapper.svelte b/src/routes/journals/ae_comp__journal_entry_obj_li_wrapper.svelte index 32a2ec22..1ffd9fdb 100644 --- a/src/routes/journals/ae_comp__journal_entry_obj_li_wrapper.svelte +++ b/src/routes/journals/ae_comp__journal_entry_obj_li_wrapper.svelte @@ -1,24 +1,24 @@ {#if $lq__journal_entry_obj_li} @@ -26,11 +26,10 @@ {lq__journal_obj} {lq__journal_entry_obj_li} {show_found_header} - {log_lvl} - /> + {log_lvl} /> {:else} - + Loading entries... {/if} diff --git a/src/routes/journals/ae_comp__journal_entry_obj_qry.svelte b/src/routes/journals/ae_comp__journal_entry_obj_qry.svelte index 5be052eb..f239f0fa 100644 --- a/src/routes/journals/ae_comp__journal_entry_obj_qry.svelte +++ b/src/routes/journals/ae_comp__journal_entry_obj_qry.svelte @@ -1,92 +1,91 @@ + class="ae_group filters_and_search flex flex-row flex-wrap items-center justify-center gap-2"> - + class="search_form flex flex-row flex-wrap items-center justify-center gap-1"> + Search: + class:dark:bg-red-800={$journals_sess.entry_li == null} /> + title="Perform detailed search"> @@ -142,12 +138,10 @@ hover:preset-filled-surface-500 transition-all " - title="Clear search query text" - > + title="Clear search query text"> + class="text-neutral-800/60 dark:text-neutral-50/60" /> Clear @@ -155,15 +149,14 @@ - Category: + Category: { handle_search_trigger(); }} - title="Filter by category" - > + title="Filter by category"> All Categories {#each $lq__journal_obj?.cfg_json?.category_li as category (category.code)} {category.name} @@ -173,8 +166,7 @@ + class="border-surface-300-700 flex flex-row flex-wrap items-center gap-2 border-l pl-2"> + class="bg-surface-500/10 sticky top-0 z-10 mx-auto mb-4 flex max-w-fit justify-center gap-1 rounded-lg p-1 backdrop-blur-sm"> (tab = 'actions')} - > + onclick={() => (tab = 'actions')}> Quick Actions (tab = 'general')} - > + onclick={() => (tab = 'general')}> General (tab = 'security')} - > + onclick={() => (tab = 'security')}> Status & Security (tab = 'ui')} - > + onclick={() => (tab = 'ui')}> UI/Visuals (tab = 'json')} - > + onclick={() => (tab = 'json')}> JSON {#if tab === 'actions'} - - + + { show = false; on_new_entry?.(); - }} - > + }}> New Journal Entry { show = false; on_show_export?.(); - }} - > + }}> Export Entries { show = false; on_show_import?.(); - }} - > + }}> Import Entries {:else if tab === 'general'} - + Journal Name + >Journal Name + placeholder="e.g. Personal Log" /> Description (Markdown) + >Description (Markdown) Type + >Type + class="select"> {#each $journals_loc.journal.type_code_li as type (type.code)} {type.name} + >{type.name} {/each} Journal Group (text) + >Journal Group (text) + placeholder="Standard" /> @@ -301,28 +316,24 @@ + class="border-surface-500/30 flex items-center gap-2 border-b pb-2 text-lg font-bold"> Journal Categories + class="bg-surface-500/5 border-surface-500/10 space-y-2 rounded-lg border p-4"> {#each tmp__journal_obj?.cfg_json?.category_li ?? [] as category, i (category.code ?? i)} - + + placeholder="Code" /> + placeholder="Display Name" /> + }}> {/each} { if (!tmp__journal_obj.cfg_json.category_li) tmp__journal_obj.cfg_json.category_li = []; @@ -347,81 +357,68 @@ code: '', name: '' }); - }} - > + }}> Add Category {:else if tab === 'security'} - + + class="border-surface-500/30 flex items-center gap-2 border-b pb-2 text-lg font-bold"> Status & Lifecycle - + + class="bg-surface-500/5 border-surface-500/10 hover:bg-surface-500/10 flex cursor-pointer items-center space-x-3 rounded-lg border p-3 transition-colors"> handle_update_journal(false)} - class="checkbox checkbox-primary" - /> + class="checkbox checkbox-primary" /> Enabled Allow access to this journal + >Allow access to this journal + class="bg-surface-500/5 border-surface-500/10 hover:bg-surface-500/10 flex cursor-pointer items-center space-x-3 rounded-lg border p-3 transition-colors"> handle_update_journal(false)} - class="checkbox checkbox-primary" - /> + class="checkbox checkbox-primary" /> Hidden Hide from standard lists + >Hide from standard lists + class="bg-surface-500/5 border-surface-500/10 hover:bg-surface-500/10 flex cursor-pointer items-center space-x-3 rounded-lg border p-3 transition-colors"> handle_update_journal(false)} - class="checkbox checkbox-primary" - /> + class="checkbox checkbox-primary" /> Priority Journal Star or pin to top + >Star or pin to top + class="bg-surface-500/5 border-surface-500/10 flex items-center justify-between rounded-lg border p-3"> - Sort Order + Sort Order Manual list position + >Manual list position + }}> {tmp__journal_obj.sort ?? 0} + class="w-8 text-center font-mono text-lg font-bold" + >{tmp__journal_obj.sort ?? 0} + }}> @@ -454,34 +448,29 @@ + class="border-surface-500/30 flex items-center gap-2 border-b pb-2 text-lg font-bold"> Encryption Passcodes + class="bg-warning-500/10 border-warning-500/30 space-y-4 rounded-lg border p-4 shadow-inner"> Primary Passcode (Stored) + class="text-xs font-bold tracking-wider uppercase opacity-70" + >Primary Passcode (Stored) + placeholder="Module-level passcode" /> Private Passcode (Double Encryption) + class="text-xs font-bold tracking-wider uppercase opacity-70" + >Private Passcode (Double Encryption) + placeholder="User-level secret" /> + class="text-warning-700 dark:text-warning-300 text-[10px] italic"> * Note: Passcodes are used locally for E2EE. Primary is often stored in the DB, while Private should remain known only to you. @@ -508,71 +495,58 @@ + onclick={delete_journal}> Delete Entire Journal {:else if tab === 'ui'} - + + class="border-surface-500/30 flex items-center gap-2 border-b pb-2 text-lg font-bold"> Default View Modes + class="bg-surface-500/5 border-surface-500/10 grid grid-cols-1 gap-6 rounded-lg border p-4 md:grid-cols-2"> Preferred Viewer + >Preferred Viewer + class="select"> Rendered HTML (Default) + >Rendered HTML (Default) Plain Text CodeMirror (Syntax) + >CodeMirror (Syntax) Preferred Editor + >Preferred Editor + class="select"> Standard Textarea + >Standard Textarea CodeMirror (Advanced) + >CodeMirror (Advanced) Color Scheme + >Color Scheme + class="select"> Default (Slate) Deep Blue Nature Green @@ -583,19 +557,16 @@ Quick Add Placement + >Quick Add Placement + class="select"> Append to End (Default) - Prepend to Start + >Append to End (Default) + Prepend to Start @@ -604,51 +575,42 @@ + class="border-surface-500/30 flex items-center gap-2 border-b pb-2 text-lg font-bold"> Entry Visibility (Global) + class="grid grid-cols-1 gap-2 sm:grid-cols-2 lg:grid-cols-3"> + class="bg-surface-500/5 border-surface-500/10 flex cursor-pointer items-center space-x-2 rounded border p-2"> + class="checkbox checkbox-sm" /> Hide Private + class="bg-surface-500/5 border-surface-500/10 flex cursor-pointer items-center space-x-2 rounded border p-2"> + class="checkbox checkbox-sm" /> Hide Personal + class="bg-surface-500/5 border-surface-500/10 flex cursor-pointer items-center space-x-2 rounded border p-2"> + class="checkbox checkbox-sm" /> Hide Professional + >Hide Professional @@ -656,193 +618,157 @@ + class="border-surface-500/30 flex items-center gap-2 border-b pb-2 text-lg font-bold"> Entry Feature Buttons + class="grid grid-cols-2 gap-2 sm:grid-cols-3 lg:grid-cols-4"> + class="bg-surface-500/5 border-surface-500/10 flex items-center gap-2 rounded border p-2"> - Hide Alert + class="checkbox checkbox-sm" /> + Hide Alert + class="bg-surface-500/5 border-surface-500/10 flex items-center gap-2 rounded border p-2"> - Hide Private + class="checkbox checkbox-sm" /> + Hide Private + class="bg-surface-500/5 border-surface-500/10 flex items-center gap-2 rounded border p-2"> - Hide Public + class="checkbox checkbox-sm" /> + Hide Public + class="bg-surface-500/5 border-surface-500/10 flex items-center gap-2 rounded border p-2"> - Hide Pers. + class="checkbox checkbox-sm" /> + Hide Pers. + class="bg-surface-500/5 border-surface-500/10 flex items-center gap-2 rounded border p-2"> - Hide Prof. + class="checkbox checkbox-sm" /> + Hide Prof. + class="bg-surface-500/5 border-surface-500/10 flex items-center gap-2 rounded border p-2"> - Hide Templ. + class="checkbox checkbox-sm" /> + Hide Templ. + class="bg-surface-500/5 border-surface-500/10 flex items-center gap-2 rounded border p-2"> - Hide Copy MD + class="checkbox checkbox-sm" /> + Hide Copy MD + class="bg-surface-500/5 border-surface-500/10 flex items-center gap-2 rounded border p-2"> - Hide Clone + class="checkbox checkbox-sm" /> + Hide Clone + class="border-surface-500/30 flex items-center gap-2 border-b pb-2 text-lg font-bold"> List Interactions - + Expansion Trigger + >Expansion Trigger + class="select"> Click to Expand Hover to Expand - + List Max Height + >List Max Height + class="select select-sm"> Default Small (16) - Medium (32) + Medium (32) Large (64) Full Active Max Height + >Active Max Height + class="select select-sm"> Default Large (64) + >Large (64) X-Large (96) + >X-Large (96) Full + >Full @@ -855,8 +781,7 @@ readonly={true} content={JSON.stringify(tmp__journal_obj, null, 2)} theme_mode={$ae_loc.theme_mode} - class_li="rounded-lg border border-surface-500/30" - /> + class_li="rounded-lg border border-surface-500/30" /> {/if} @@ -865,16 +790,14 @@ (show = false)} - > + class="btn preset-tonal-surface min-w-[100px] font-bold" + onclick={() => (show = false)}> Cancel handle_update_journal(true)} - > + class="btn preset-filled-primary min-w-[120px] font-bold" + onclick={() => handle_update_journal(true)}> Save Changes diff --git a/src/routes/journals/ae_comp__journal_obj_id_view.svelte b/src/routes/journals/ae_comp__journal_obj_id_view.svelte index 72c855df..fffe1c7c 100644 --- a/src/routes/journals/ae_comp__journal_obj_id_view.svelte +++ b/src/routes/journals/ae_comp__journal_obj_id_view.svelte @@ -1,265 +1,265 @@ - + + 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"> + - - - - {@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}> + + + + {@html $lq__journal_obj?.name ?? 'Loading...'} - {#if $ae_loc.edit_mode} - - {$lq__journal_entry_obj_li?.length ?? '0'}× - - {/if} + {#if $ae_loc.edit_mode} + + {$lq__journal_entry_obj_li?.length ?? '0'}× + + {/if} - {#await $journals_prom.load__journal_entry_obj_li} - - {/await} - + {#await $journals_prom.load__journal_entry_obj_li} + + {/await} + - - - - ($journals_sess.show__modal_edit__journal_obj = true)} - class="btn preset-tonal-secondary py-1 px-3 shadow-md" - title="Journal Config & Actions" - > - - Config - + + + + ($journals_sess.show__modal_edit__journal_obj = true)} + class="btn preset-tonal-secondary px-3 py-1 shadow-md" + title="Journal Config & Actions"> + + Config + - - {#if !$journals_sess?.journal_kv[$lq__journal_obj?.id]?.journal_passcode_verified} - - - - {/if} - - + + {#if !$journals_sess?.journal_kv[$lq__journal_obj?.id]?.journal_passcode_verified} + + + + {/if} + + - - {#if $lq__journal_obj?.description && $ae_loc.edit_mode} - - {@html $lq__journal_obj.description_md_html} - - {/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} + + {/if} @@ -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} /> diff --git a/src/routes/journals/ae_comp__journal_obj_li.svelte b/src/routes/journals/ae_comp__journal_obj_li.svelte index 904cb345..5c1ac488 100644 --- a/src/routes/journals/ae_comp__journal_obj_li.svelte +++ b/src/routes/journals/ae_comp__journal_obj_li.svelte @@ -1,19 +1,19 @@ - + + 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/list:opacity-25 dark:opacity-20 dark:group-hover/list:opacity-35"> + - + {#if $lq__journal_obj_li && $lq__journal_obj_li.length} {#each $lq__journal_obj_li as journal (journal.journal_id)} + class:!border-l-warning-500={!journal?.enable}> - + - + {journal.name} - + {#if journal.type_code} - + {journal.type_code} {/if} {#if journal.description && $ae_loc.edit_mode} - - {ae_util.strip_html ? ae_util.strip_html(journal.description).slice(0, 60) : journal.description.slice(0, 60)}… + + {ae_util.strip_html + ? ae_util + .strip_html(journal.description) + .slice(0, 60) + : journal.description.slice( + 0, + 60 + )}… {/if} - - + - {journal.journal_entry_count ?? 0}× + {journal.journal_entry_count ?? + 0}× - + - {ae_util.iso_datetime_formatter( - journal.updated_on || journal.created_on, - 'date_short' - )} - - {#if $ae_loc.edit_mode && $ae_loc.administrator_access} - - - {ae_util.iso_datetime_formatter( - journal.created_on, + {ae_util.iso_datetime_formatter( + journal.updated_on || journal.created_on, 'date_short' )} + + {#if $ae_loc.edit_mode && $ae_loc.administrator_access} + + + {ae_util.iso_datetime_formatter( + journal.created_on, + 'date_short' + )} {/if} - + {#if $ae_loc.edit_mode} {#if journal.hide} - 🚫 + 🚫 {/if} {#if !journal.enable} - ⚠️ + ⚠️ {/if} {/if} {/each} {:else} - + No journals found in this view. diff --git a/src/routes/journals/ae_comp__modal_journal_config.svelte b/src/routes/journals/ae_comp__modal_journal_config.svelte index 9f33842e..61bc3af3 100644 --- a/src/routes/journals/ae_comp__modal_journal_config.svelte +++ b/src/routes/journals/ae_comp__modal_journal_config.svelte @@ -1,50 +1,63 @@ + footerClass="flex flex-row gap-2 items-center justify-center w-full bg-orange-100 dark:bg-orange-900 p-4 rounded-b-lg border-t border-orange-200 dark:border-orange-800"> {#snippet header()} - + Æ Journals Module Config - (show = false)}> + (show = false)}> {/snippet} - + + class="bg-surface-500/10 sticky top-0 z-10 mx-auto mb-4 flex max-w-fit justify-center gap-1 rounded-lg p-1 backdrop-blur-sm"> (tab = 'form')} - > + onclick={() => (tab = 'form')}> Config (tab = 'local_json')} - > + onclick={() => (tab = 'local_json')}> Local JSON (tab = 'session_json')} - > + onclick={() => (tab = 'session_json')}> Session JSON {#if tab === 'form'} - + + class="border-surface-500/30 flex items-center gap-2 border-b pb-2 text-xl font-bold"> Date and Time Display - + DateTime Format + >DateTime Format + class="select select-sm"> MMM D, YY hh:mm A + >MMM D, YY hh:mm A MMMM D, YYYY hh:mm A + >MMMM D, YYYY hh:mm A MMM D, YY HH:mm + >MMM D, YY HH:mm MMMM D, YYYY HH:mm + >MMMM D, YYYY HH:mm US (MM/DD/YYYY hh:mm:ss A) + >US (MM/DD/YYYY hh:mm:ss A) ISO (YYYY-MM-DD HH:mm:ss) + >ISO (YYYY-MM-DD HH:mm:ss) Time-Only Format + >Time-Only Format + class="select select-sm"> 12-hour short (3:30 PM) + >12-hour short (3:30 PM) 12-hour long (3:30:45 PM) + >12-hour long (3:30:45 PM) 24-hour short (15:30) + >24-hour short (15:30) 24-hour long (15:30:45) + >24-hour long (15:30:45) @@ -168,23 +164,19 @@ + class="border-surface-500/30 flex items-center gap-2 border-b pb-2 text-xl font-bold"> + class="text-primary-500" /> User Interface Preferences - + + class="bg-surface-500/5 border-surface-500/10 flex cursor-pointer items-center space-x-3 rounded-lg border p-2"> + class="checkbox" /> Enable Auto-Save @@ -193,16 +185,14 @@ + class="bg-surface-500/5 border-surface-500/10 flex cursor-pointer items-center space-x-3 rounded-lg border p-2"> + class="checkbox" /> - Show Technical IDs + Show Technical IDs Display UUIDs in metadata footers @@ -214,52 +204,42 @@ + class="border-surface-500/30 flex items-center gap-2 border-b pb-2 text-xl font-bold"> Journal Query Filters - + Enabled Status + >Enabled Status + class="select select-sm"> Enabled Only Disabled Only + >Disabled Only All (Enabled & Disabled & NULL) + >All (Enabled & Disabled & NULL) Hidden Status + >Hidden Status + class="select select-sm"> Visible Only Hidden Only All (Visible & Hidden & NULL) + >All (Visible & Hidden & NULL) Query Limit + >Query Limit + class="select select-sm"> 10 20 50 @@ -275,52 +255,42 @@ + class="border-surface-500/30 flex items-center gap-2 border-b pb-2 text-xl font-bold"> Entry Query Filters - + Enabled Status + >Enabled Status + class="select select-sm"> Enabled Only Disabled Only + >Disabled Only All (Enabled & Disabled & NULL) + >All (Enabled & Disabled & NULL) Hidden Status + >Hidden Status + class="select select-sm"> Visible Only Hidden Only All (Visible & Hidden & NULL) + >All (Visible & Hidden & NULL) Query Limit + >Query Limit + class="select select-sm"> 10 20 50 @@ -336,30 +306,25 @@ + class="border-surface-500/30 flex items-center gap-2 border-b pb-2 text-xl font-bold"> Security & Encryption - + class="space-y-4 rounded-lg border border-orange-500/20 bg-orange-500/5 p-4"> + Global security overrides for the journal module. + class="flex cursor-pointer items-center space-x-3"> + class="checkbox checkbox-primary" /> Cache Passcodes in Session + >Cache Passcodes in Session @@ -370,8 +335,7 @@ readonly={true} content={JSON.stringify(tmp_config, null, 2)} theme_mode={$ae_loc.theme_mode} - class_li="rounded-lg border border-surface-500/30" - /> + class_li="rounded-lg border border-surface-500/30" /> {:else if tab === 'session_json'} @@ -379,8 +343,7 @@ readonly={true} content={JSON.stringify($journals_sess, null, 2)} theme_mode={$ae_loc.theme_mode} - class_li="rounded-lg border border-surface-500/30" - /> + class_li="rounded-lg border border-surface-500/30" /> {/if} @@ -389,16 +352,14 @@ (show = false)} - > + class="btn preset-tonal-surface min-w-[100px] font-bold" + onclick={() => (show = false)}> Cancel + class="btn preset-filled-primary min-w-[120px] font-bold shadow-lg" + onclick={handle_save}> Save Changes diff --git a/src/routes/journals/ae_comp__modal_journal_entry_append.svelte b/src/routes/journals/ae_comp__modal_journal_entry_append.svelte index 0bdabe53..ff5143be 100644 --- a/src/routes/journals/ae_comp__modal_journal_entry_append.svelte +++ b/src/routes/journals/ae_comp__modal_journal_entry_append.svelte @@ -1,138 +1,135 @@ + class="top-center relative mx-auto flex w-full flex-col gap-1 divide-gray-200 rounded-lg border-gray-200 bg-white text-gray-800 shadow-md dark:divide-gray-700 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-200"> @@ -155,8 +151,7 @@ type="checkbox" id="append_timestamp_header" bind:checked={add_timestamp_header} - class="checkbox" - /> + class="checkbox" /> Use timestamp as Markdown header @@ -165,8 +160,7 @@ type="checkbox" id="append_timestamp_header_w_day_of_week" bind:checked={add_timestamp_header_w_day_of_week} - class="checkbox" - /> + class="checkbox" /> Include day of week @@ -176,8 +170,7 @@ type="text" placeholder="Markdown header for content (Optional)" bind:value={add_text_header} - class="input" - /> + class="input" /> + : mode}..."> - + + class:opacity-50={!has_changes}> Update + class="btn preset-tonal-surface"> Cancel diff --git a/src/routes/journals/ae_comp__modal_journal_entry_config.svelte b/src/routes/journals/ae_comp__modal_journal_entry_config.svelte index b3e63da4..011ec1fe 100644 --- a/src/routes/journals/ae_comp__modal_journal_entry_config.svelte +++ b/src/routes/journals/ae_comp__modal_journal_entry_config.svelte @@ -1,89 +1,108 @@ + footerClass="flex flex-row gap-2 items-center justify-center w-full bg-orange-100 dark:bg-orange-900 p-4 rounded-b-lg border-t border-orange-200 dark:border-orange-800"> {#snippet header()} - + Entry Config: {tmp_entry_obj.name || '--'} - (show = false)}> + (show = false)}> {/snippet} - + + class="bg-surface-500/10 sticky top-0 z-10 mx-auto mb-4 flex max-w-fit justify-center gap-1 rounded-lg p-1 backdrop-blur-sm"> (tab = 'actions')} - > + onclick={() => (tab = 'actions')}> Quick Actions (tab = 'meta')} - > + onclick={() => (tab = 'meta')}> Metadata (tab = 'security')} - > + onclick={() => (tab = 'security')}> Status & Security (tab = 'json')} - > + onclick={() => (tab = 'json')}> JSON {#if tab === 'actions'} - - + + { show = false; on_prepend?.(); - }} - > + }}> Prepend Content { show = false; on_append?.(); - }} - > + }}> Append Content { show = false; on_show_export?.(); - }} - > + }}> Export Entry + }}> Clone Entry - + Quick Category @@ -211,8 +223,7 @@ tmp_entry_obj.category_code = cat.code; handle_update_entry(); on_save(); - }} - > + }}> {cat.name} {/each} @@ -220,7 +231,7 @@ {:else if tab === 'meta'} - + Category { handle_update_entry(); on_save(); - }} - > + }}> None {#each journal?.cfg_json?.category_li ?? [] as cat (cat.code)} {cat.name} @@ -240,9 +250,8 @@ Tags (Comma separated) - + >Tags (Comma separated) + { handle_update_entry(); on_save(); - }} - /> + }} /> - + Archive On + >Archive On + class="input" /> Sort Priority + >Sort Priority - {tmp_entry_obj.sort ?? 0} + }}> + {tmp_entry_obj.sort ?? 0} + }}> {:else if tab === 'security'} - + + class="border-surface-500/30 flex items-center gap-2 border-b pb-2 text-lg font-bold"> Status & Security - + + class="bg-surface-500/5 border-surface-500/10 hover:bg-surface-500/10 flex cursor-pointer items-center space-x-3 rounded-lg border p-3 transition-colors"> + class="checkbox checkbox-primary" /> Enabled Allow access to this entry + >Allow access to this entry + class="bg-surface-500/5 border-surface-500/10 hover:bg-surface-500/10 flex cursor-pointer items-center space-x-3 rounded-lg border p-3 transition-colors"> + class="checkbox checkbox-primary" /> Hidden Hide from standard lists + >Hide from standard lists + class="bg-surface-500/5 border-surface-500/10 hover:bg-surface-500/10 flex cursor-pointer items-center space-x-3 rounded-lg border p-3 transition-colors"> + class="checkbox checkbox-primary" /> Priority Entry Star or pin to top + >Star or pin to top + class="bg-surface-500/5 border-surface-500/10 flex items-center justify-between rounded-lg border p-3"> - Sort Order + Sort Order Manual list position + >Manual list position + }}> {tmp_entry_obj.sort ?? 0} + class="w-8 text-center font-mono text-lg font-bold" + >{tmp_entry_obj.sort ?? 0} + }}> @@ -429,21 +416,18 @@ hide_personal={journal?.cfg_json?.hide_btn_personal} hide_professional={journal?.cfg_json ?.hide_btn_professional} - hide_template={journal?.cfg_json?.hide_btn_template} - /> + hide_template={journal?.cfg_json?.hide_btn_template} /> {#if tmp_entry_obj.private && !tmp_entry_obj.content && tmp_entry_obj.content_encrypted} - + + class="bg-error-500/10 border-error-500/30 rounded-lg border p-4"> + class="text-error-500 mb-2 flex items-center gap-2 font-bold"> Disaster Recovery - + If the encryption passcode is lost, the data is unrecoverable. You can force a reset to plain text to reuse this entry ID. @@ -454,8 +438,7 @@ onclick={() => { show = false; on_force_reset?.(); - }} - > + }}> Force Reset to Plain Text @@ -468,8 +451,7 @@ class="btn btn-sm preset-tonal-error w-full" onclick={() => { alert('Delete logic handled in parent component'); - }} - > + }}> Delete Entry @@ -480,8 +462,7 @@ readonly={true} content={JSON.stringify(tmp_entry_obj, null, 2)} theme_mode={$ae_loc.theme_mode} - class_li="rounded-lg border border-surface-500/30" - /> + class_li="rounded-lg border border-surface-500/30" /> {/if} @@ -489,9 +470,8 @@ {#snippet footer()} (show = false)} - > + class="btn preset-filled-primary min-w-[120px] font-bold" + onclick={() => (show = false)}> Done diff --git a/src/routes/journals/ae_comp__modal_journal_export.svelte b/src/routes/journals/ae_comp__modal_journal_export.svelte index 8b499dfa..86975860 100644 --- a/src/routes/journals/ae_comp__modal_journal_export.svelte +++ b/src/routes/journals/ae_comp__modal_journal_export.svelte @@ -1,107 +1,113 @@ + class="w-full"> + class="flex items-center justify-between rounded-lg bg-blue-50 p-4 text-blue-800 dark:bg-blue-900/20 dark:text-blue-200"> Ready to Export: {export_count} entries. @@ -122,8 +126,7 @@ {#if journal} Journal Type: {journal.type_code || 'standard'} + >{journal.type_code || 'standard'} {/if} @@ -134,19 +137,18 @@ Select Export Template - + {#each templates as template (template.id)} { selected_template_id = template.id; generate_preview(); - }} - > + }}> {#if template.extension === 'json'} {:else if template.extension === 'html'} @@ -154,12 +156,10 @@ {:else} {/if} - {template.name} + {template.name} .{template.extension} + >.{template.extension} {/each} @@ -167,43 +167,38 @@ - + Preview - {selected_template.name} + {selected_template.name} 5000 ? '\n... (truncated for preview)' - : '')} - > + : '')}> - + Close + onclick={on_close}>Close + onclick={handle_copy}> Copy to Clipboard + onclick={handle_download}> Download File diff --git a/src/routes/journals/ae_comp__modal_journal_import.svelte b/src/routes/journals/ae_comp__modal_journal_import.svelte index 09aed5fa..67a8fb0b 100644 --- a/src/routes/journals/ae_comp__modal_journal_import.svelte +++ b/src/routes/journals/ae_comp__modal_journal_import.svelte @@ -1,142 +1,145 @@ + class="w-full"> - + Parser Strategy Standard (1 File = 1 Entry) + >Standard (1 File = 1 Entry) Personal Log (Split by Date) + >Personal Log (Split by Date) Amazon Vine Reviews @@ -173,25 +173,23 @@ - document.getElementById('file_import_input')?.click()} - > + document.getElementById('file_import_input')?.click()}> Click to upload + class="text-primary-600 hover:text-primary-500 font-semibold" + >Click to upload or drag and drop @@ -204,17 +202,15 @@ class="hidden" multiple accept=".md,.txt" - onchange={(e) => (files = e.currentTarget.files)} - /> + onchange={(e) => (files = e.currentTarget.files)} /> - + class="max-h-64 overflow-y-auto rounded-lg border bg-gray-50 p-2 dark:bg-gray-900"> + Preview ({parsed_entries.length} entries) {#if is_parsing} @@ -222,7 +218,7 @@ {#if parsed_entries.length > 0} - + Name @@ -234,9 +230,8 @@ {#each parsed_entries as entry, i (i)} {entry.name} + class="max-w-[200px] truncate" + title={entry.name}>{entry.name} {entry.created_on?.substring(0, 10)} {entry.tags.join(', ')} @@ -244,11 +239,11 @@ {:else if files && files.length > 0 && !is_parsing} - + No entries found in selected files. {:else if !files} - + Select files to preview import. {/if} @@ -257,8 +252,7 @@ {#if import_log.length > 0} + class="max-h-32 overflow-y-auto rounded bg-black p-2 font-mono text-xs text-green-400"> {#each import_log as log, i (i)} {log} {/each} @@ -269,14 +263,12 @@ Cancel + onclick={on_close}>Cancel + onclick={handle_import}> {#if is_importing} Importing... {:else} diff --git a/src/routes/journals/ae_comp__obj_core_props.svelte b/src/routes/journals/ae_comp__obj_core_props.svelte index 14c25922..cedc6f62 100644 --- a/src/routes/journals/ae_comp__obj_core_props.svelte +++ b/src/routes/journals/ae_comp__obj_core_props.svelte @@ -1,105 +1,104 @@ + class="ae_meta flex w-full flex-row flex-wrap items-center justify-between gap-1"> + class="flex flex-row flex-wrap items-center justify-center rounded-lg border border-gray-300"> { obj_sort = obj_sort ? obj_sort + 1 : 1; // update_journal_entry(); }} - class="btn-icon btn-icon-sm preset-tonal-tertiary transition hover:preset-filled-tertiary-500" - title="Increment sort order of this journal entry" - > + class="btn-icon btn-icon-sm preset-tonal-tertiary hover:preset-filled-tertiary-500 transition" + title="Increment sort order of this journal entry"> @@ -154,9 +150,8 @@ obj_sort = obj_sort ? obj_sort - 1 : 0; // update_journal_entry(); }} - class="btn-icon btn-icon-sm preset-tonal-tertiary transition hover:preset-filled-tertiary-500" - title="Decrement sort order of this journal entry" - > + class="btn-icon btn-icon-sm preset-tonal-tertiary hover:preset-filled-tertiary-500 transition" + title="Decrement sort order of this journal entry"> @@ -171,13 +166,11 @@ }} class:hidden={!$ae_loc.edit_mode} class="input input-sm input-bordered w-24" - title="Set group (for sorting) of this journal entry" - /> + title="Set group (for sorting) of this journal entry" /> + class="flex flex-row flex-wrap items-center justify-center rounded-lg border border-gray-200"> + title="Set archive on datetime for archiving this journal entry" /> {#if obj_archive_on} @@ -200,8 +192,7 @@ }} class:hidden={!$ae_loc.edit_mode} class="btn-icon btn-icon-sm preset-tonal-warning hover:preset-filled-warning-500 transition" - title="Clear the archive on datetime for this journal entry" - > + title="Clear the archive on datetime for this journal entry"> @@ -221,8 +212,7 @@ }} class:hidden={!$ae_loc.edit_mode} class="btn-icon btn-icon-sm preset-tonal-warning hover:preset-filled-warning-500 transition" - title="Set the archive on datetime for this journal entry" - > + title="Set the archive on datetime for this journal entry"> @@ -237,8 +227,7 @@ update_journal_entry(); }} class="btn btn-sm md:btn-md preset-tonal-warning hover:preset-filled-warning-500 transition" - title="Toggle visibility of this journal entry" - > + title="Toggle visibility of this journal entry"> {#if obj_hide} Hidden @@ -257,8 +246,7 @@ }} class:hidden={!$ae_loc.administrator_access || !$ae_loc.edit_mode} class="btn btn-sm md:btn-md preset-tonal-error hover:preset-filled-error-500 transition" - title="Toggle enable status of this journal entry" - > + title="Toggle enable status of this journal entry"> {#if obj_enable} Enabled @@ -304,8 +292,7 @@ }} class:hidden={!$ae_loc.edit_mode} class="btn btn-sm md:btn-md preset-tonal-error hover:preset-filled-error-500 transition" - title="Delete this journal entry" - > + title="Delete this journal entry"> {#if $ae_loc.administrator_access && $ae_loc.edit_mode} Delete @@ -316,8 +303,7 @@ + class="flex flex-row items-center justify-center text-sm text-gray-500"> {#if !$ae_loc.edit_mode} {ae_util.iso_datetime_formatter( @@ -344,19 +330,18 @@ {#if $ae_loc.edit_mode && lq__journal_obj_li?.length} + class="flex flex-row flex-wrap items-center justify-start gap-2 rounded-lg border border-gray-200"> - + Journal: { @@ -372,14 +357,12 @@ change_journal_id(); } }} - title="Select a different journal for this entry" - > + title="Select a different journal for this entry"> Select Journal {#each lq__journal_obj_li as journal (journal.journal_id)} + title={`Journal: ${journal.name}`}> {journal.name} {/each} diff --git a/src/routes/journals/journal_entry_visibility.test.ts b/src/routes/journals/journal_entry_visibility.test.ts index 14be4fe0..4eb46a5a 100644 --- a/src/routes/journals/journal_entry_visibility.test.ts +++ b/src/routes/journals/journal_entry_visibility.test.ts @@ -30,33 +30,49 @@ describe('Journal Entry Visibility Filtering', () => { { id: '1', name: 'Normal Entry', hide: false, enable: true }, { id: '2', name: 'Hidden Entry', hide: true, enable: true }, { id: '3', name: 'Disabled Entry', hide: false, enable: false }, - { id: '4', name: 'Hidden & Disabled', hide: true, enable: false }, + { id: '4', name: 'Hidden & Disabled', hide: true, enable: false } ]; it('should show only normal entries when Edit Mode is OFF (Manager)', () => { - const ae_loc = { edit_mode: false, trusted_access: true, administrator_access: true }; + const ae_loc = { + edit_mode: false, + trusted_access: true, + administrator_access: true + }; const result = filterEntries(mockEntries, ae_loc); expect(result?.length).toBe(1); expect(result?.[0].id).toBe('1'); }); it('should show hidden entries to Trusted users when Edit Mode is ON', () => { - const ae_loc = { edit_mode: true, trusted_access: true, administrator_access: false }; + const ae_loc = { + edit_mode: true, + trusted_access: true, + administrator_access: false + }; const result = filterEntries(mockEntries, ae_loc); // Should see Normal (1) and Hidden (2). Should NOT see Disabled (3, 4) expect(result?.length).toBe(2); - expect(result?.map(r => r.id)).toContain('1'); - expect(result?.map(r => r.id)).toContain('2'); + expect(result?.map((r) => r.id)).toContain('1'); + expect(result?.map((r) => r.id)).toContain('2'); }); it('should show everything to Administrators when Edit Mode is ON', () => { - const ae_loc = { edit_mode: true, trusted_access: true, administrator_access: true }; + const ae_loc = { + edit_mode: true, + trusted_access: true, + administrator_access: true + }; const result = filterEntries(mockEntries, ae_loc); expect(result?.length).toBe(4); }); it('should hide everything sensitive to Public users even if Edit Mode is ON (Safety Check)', () => { - const ae_loc = { edit_mode: true, trusted_access: false, administrator_access: false }; + const ae_loc = { + edit_mode: true, + trusted_access: false, + administrator_access: false + }; const result = filterEntries(mockEntries, ae_loc); expect(result?.length).toBe(1); expect(result?.[0].id).toBe('1');
- {[$ae_loc.person.given_name, $ae_loc.person.family_name].filter(Boolean).join(' ')} + {[$ae_loc.person.given_name, $ae_loc.person.family_name] + .filter(Boolean) + .join(' ')}
Accessing Brain...
+
You haven't created any journals yet. Start by creating one to begin your documentation journey.
Loading Journal...
You must be logged in as the owner to view this Journal.
You must be logged in as the owner to view this Journal Entry.
+ class="text-error-500 text-xs font-bold tracking-widest uppercase"> Decryption failed. Incorrect passcode.
Passcode lost? You can force a reset to plain text, but all currently encrypted data will be permanently deleted. @@ -82,8 +79,7 @@ + onclick={on_force_reset}> Force Reset to Plain Text @@ -98,14 +94,12 @@ bind:editor_view theme_mode={$ae_loc.theme_mode} placeholder="Write using Markdown..." - class_li="p-2 preset-outlined-warning-300-700 shadow-lg rounded-lg w-full max-w-6xl bg-surface-50 dark:bg-surface-800" - /> + class_li="p-2 preset-outlined-warning-300-700 shadow-lg rounded-lg w-full max-w-6xl bg-surface-50 dark:bg-surface-800" /> {:else} + class="textarea h-[500px] w-full max-w-6xl grow rounded-lg border-orange-500/30 p-4 font-mono break-words whitespace-pre-wrap shadow-lg" + placeholder="Edit content..."> {/if} @@ -113,9 +107,8 @@ type="button" onclick={on_save} disabled={!has_changed} - class="btn btn-sm md:btn-md lg:btn-lg fixed top-72 right-6 min-w-32 preset-filled-success shadow-xl z-20 transition-all" - class:hidden={!has_changed} - > + class="btn btn-sm md:btn-md lg:btn-lg preset-filled-success fixed top-72 right-6 z-20 min-w-32 shadow-xl transition-all" + class:hidden={!has_changed}> Save @@ -124,16 +117,14 @@ type="button" onclick={on_save} disabled={!has_changed} - class="btn preset-tonal-warning hover:preset-filled-warning-500 w-full max-w-96 mt-4" - class:invisible={!has_changed} - > + class="btn preset-tonal-warning hover:preset-filled-warning-500 mt-4 w-full max-w-96" + class:invisible={!has_changed}> Save Changes {#if updated_idb}
+ class="text-error-500 mt-2 animate-pulse text-xs font-bold tracking-widest uppercase"> IDB object updated since last load!
+ class="text-surface-500 bg-surface-500/5 rounded-xl p-4 text-center text-sm italic"> No files attached to this entry.
Select from existing hosted files:
Loading visible entries...
+ No Journal Entry available to show. Please check the query + filters or create a new Entry. +
- No Journal Entry available to show. Please check the query - filters or create a new Entry. -
Loading entries...
No journals found in this view.
@@ -193,16 +185,14 @@
Display UUIDs in metadata footers
If the encryption passcode is lost, the data is unrecoverable. You can force a reset to plain text to reuse this entry ID. @@ -454,8 +438,7 @@ onclick={() => { show = false; on_force_reset?.(); - }} - > + }}> Force Reset to Plain Text
Click to upload + class="text-primary-600 hover:text-primary-500 font-semibold" + >Click to upload or drag and drop
@@ -204,17 +202,15 @@ class="hidden" multiple accept=".md,.txt" - onchange={(e) => (files = e.currentTarget.files)} - /> + onchange={(e) => (files = e.currentTarget.files)} />