792 lines
36 KiB
Svelte
792 lines
36 KiB
Svelte
<script lang="ts">
|
|
let log_lvl: number = 0;
|
|
|
|
// *** Import Svelte specific
|
|
import { goto, invalidate, pushState, replaceState } from '$app/navigation';
|
|
import { Modal } from 'flowbite-svelte';
|
|
import {
|
|
CalendarClock, Check, CodeXml, Copy,
|
|
Eye, EyeOff,
|
|
FileLock, Fingerprint, Flag, FlagOff,
|
|
Group,
|
|
ListPlus, Lock,
|
|
NotebookPen, NotebookText, NotepadTextDashed,
|
|
RemoveFormatting,
|
|
Shapes, Siren,
|
|
Tags, TypeOutline,
|
|
X
|
|
} from '@lucide/svelte';
|
|
|
|
|
|
// *** Import Aether specific variables and functions
|
|
import type { key_val } from '$lib/ae_stores';
|
|
import { ae_util } from '$lib/ae_utils/ae_utils';
|
|
import { api } from '$lib/api';
|
|
import { ae_snip, ae_loc, ae_sess, ae_api, ae_trig, slct, slct_trigger } from '$lib/ae_stores';
|
|
import { journals_loc, journals_sess, journals_slct, journals_trig } from '$lib/ae_journals/ae_journals_stores';
|
|
import { journals_func } from '$lib/ae_journals/ae_journals_functions';
|
|
|
|
interface Props {
|
|
lq__journal_obj: any;
|
|
lq__journal_entry_obj_li: any;
|
|
}
|
|
|
|
let { lq__journal_obj, lq__journal_entry_obj_li }: Props = $props();
|
|
|
|
let ae_promises: key_val = $state({});
|
|
// let ae_tmp: key_val = {};
|
|
// 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>
|
|
|
|
|
|
<section class="journal_list flex flex-col gap-1 md:gap-2 items-center justify-center w-full">
|
|
{#if $lq__journal_entry_obj_li && $lq__journal_entry_obj_li.length}
|
|
|
|
<!-- <div class="ae_group">
|
|
<span class="ae_label">Group:</span>
|
|
<span class="ae_value">{current_group}</span> -->
|
|
|
|
{#each $lq__journal_entry_obj_li as journals_journal_entry_obj, index}
|
|
|
|
|
|
|
|
|
|
<div
|
|
class="
|
|
container journal journal_entry_obj
|
|
border border-1
|
|
px-2 py-1 space-y-1
|
|
w-full max-w-screen-lg
|
|
flex flex-col items-center justify-center
|
|
bg-white text-gray-900
|
|
dark:bg-gray-800 dark:text-gray-200
|
|
rounded-lg
|
|
hover:bg-gray-100
|
|
hover:border-gray-300
|
|
transition-all duration-500 ease-out
|
|
"
|
|
class:dim={!journals_journal_entry_obj.enable}
|
|
class:bg-warning-100={!journals_journal_entry_obj?.enable}
|
|
>
|
|
<header class="ae_header flex flex-row gap-2 items-center justify-between w-full">
|
|
|
|
<span class="flex flex-row flex-wrap gap-1">
|
|
|
|
|
|
<span class="journal_entry__name *:hover:inline-block">
|
|
{#if (journals_journal_entry_obj.alert)}
|
|
<Siren size="1.25em" class="mx-1 inline-block text-red-500"/>
|
|
{/if}
|
|
|
|
{#if (journals_journal_entry_obj.priority)}
|
|
<Flag size="1.25em" class="mx-1 inline-block text-yellow-500"/>
|
|
{/if}
|
|
|
|
{#if (journals_journal_entry_obj.group)}
|
|
<Group size="1.25em" class="mx-1 inline-block text-green-500"/>
|
|
<span class="text-xs text-gray-500 hidden">Group:</span>
|
|
<span class="font-semibold text-sm text-gray-500 hidden md:inline">
|
|
{journals_journal_entry_obj.group}
|
|
</span>
|
|
{/if}
|
|
</span>
|
|
|
|
<h3
|
|
class:dim={journals_journal_entry_obj.hide}
|
|
class="journal__name h4"
|
|
>
|
|
|
|
{#if journals_journal_entry_obj.template}
|
|
<NotepadTextDashed class="mx-1 inline-block" />
|
|
{@html journals_journal_entry_obj.name ?? '-- no name --'}
|
|
{:else if (journals_journal_entry_obj.name)}
|
|
<NotebookText class="mx-1 inline-block" />
|
|
{@html journals_journal_entry_obj.name}
|
|
{:else}
|
|
<CalendarClock class="mx-1 inline-block" />
|
|
{ae_util.iso_datetime_formatter(journals_journal_entry_obj.created_on, 'datetime_iso_12_no_seconds')}
|
|
{/if}
|
|
|
|
</h3>
|
|
|
|
<span class="flex flex-row flex-wrap gap-1 items-center justify-center">
|
|
{#if !journals_journal_entry_obj.private}
|
|
<!-- Button to copy the Markdown version -->
|
|
<button
|
|
type="button"
|
|
onclick={() => {
|
|
let tmp_entry_obj = journals_journal_entry_obj;
|
|
|
|
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 variant-soft-secondary hover:variant-filled-secondary *:hover:inline text-xs lg:text-sm"
|
|
title="Copy the markdown content"
|
|
>
|
|
<!-- <span class="fas fa-copy mx-1"></span> -->
|
|
<Copy size="1em" />
|
|
<RemoveFormatting size="1.25em" />
|
|
<span class="hidden">
|
|
Copy Plaintext Markdown
|
|
</span>
|
|
</button>
|
|
|
|
<!-- Button to copy the rendered to HTML version -->
|
|
<button
|
|
type="button"
|
|
onclick={() => {
|
|
// Copy the rendered HTML content to clipboard
|
|
// const htmlContent = $lq__journal_entry_obj?.content_md_html || '';
|
|
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 p-1 variant-soft-secondary hover:variant-filled-secondary *:hover:inline lg:text-xs"
|
|
title="Copy the rendered HTML content"
|
|
>
|
|
<!-- <span class="fas fa-copy mx-1"></span> -->
|
|
<Copy size="1em" />
|
|
<CodeXml size="1.25em" />
|
|
<span class="hidden">
|
|
Copy HTML Markup
|
|
</span>
|
|
</button>
|
|
|
|
<!-- Button to copy the rich text (rendered HTML) version -->
|
|
<button
|
|
type="button"
|
|
onclick={async () => {
|
|
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;
|
|
}
|
|
|
|
try {
|
|
// Get the rendered HTML content
|
|
const htmlContent = element.innerHTML;
|
|
|
|
// Use the Clipboard API to write the HTML content as rich text
|
|
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 variant-soft-secondary *:hover:inline lg:text-xs"
|
|
title="Copy the rich text (rendered HTML) content"
|
|
>
|
|
<Copy size="1em" />
|
|
<TypeOutline size="1.25em" />
|
|
<span class="hidden">Copy Rich Text</span>
|
|
</button>
|
|
|
|
|
|
<!-- Clone entry -->
|
|
<button
|
|
type="button"
|
|
onclick={() => {
|
|
// Clone the journal entry
|
|
// We only want to clone certain fields from the original journal entry object to avoid conflicts.
|
|
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) => {
|
|
alert('Journal entry cloned successfully!');
|
|
goto(`/journals/${result.journal_id_random}/entry/${result.journal_entry_id_random}`);
|
|
}).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 p-1 variant-soft-secondary hover:variant-filled-secondary *:hover:inline lg:text-xs"
|
|
title="Clone this journal entry"
|
|
>
|
|
<!-- class="btn btn-sm variant-soft-surface hover:variant-filled-warning transition py-1 px-2" -->
|
|
<!-- <Copy strokeWidth="1" /> -->
|
|
<Copy size="1.25em" />
|
|
<span class="hidden md:inline">Clone</span>
|
|
</button>
|
|
|
|
<!-- </span> -->
|
|
|
|
{:else}
|
|
|
|
<!-- <span class="flex flex-row flex-wrap gap-1 items-center justify-center"> -->
|
|
<Lock size="1.25em" class="mx-1 inline-block text-red-400 dark:text-red-600" />
|
|
<!-- <EyeOff size="1.25em" class="mx-1 inline-block text-red-400 dark:text-red-600" /> -->
|
|
<span class="text-xs text-gray-500 hidden">Private</span>
|
|
|
|
<!-- Button to copy the Markdown version -->
|
|
<button
|
|
type="button"
|
|
onclick={() => {
|
|
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 p-1 variant-soft-secondary hover:variant-filled-secondary *:hover:inline text-xs lg:text-sm"
|
|
title="Copy the encrypted content"
|
|
>
|
|
<!-- <span class="fas fa-copy mx-1"></span> -->
|
|
<Copy size="1em" />
|
|
<Fingerprint size="1.25em" />
|
|
<span class="hidden">
|
|
Copy Encrypted
|
|
</span>
|
|
</button>
|
|
|
|
<!-- </span> -->
|
|
|
|
{/if}
|
|
</span>
|
|
</span>
|
|
|
|
|
|
<div class="flex flex-row flex-wrap gap-2 items-center justify-end">
|
|
<!-- Tags for journal entry. Comma delimited list. -->
|
|
{#if journals_journal_entry_obj.tags && journals_journal_entry_obj.tags.length}
|
|
<div class="tags flex flex-wrap gap-1 items-center justify-start p-1">
|
|
<Tags class="mx-1 inline-block"/>
|
|
<span class="text-sm text-gray-500 hidden md:inline">Tags:</span>
|
|
|
|
{#each journals_journal_entry_obj.tags.split(',') as tag}
|
|
<span
|
|
class="btn btn-sm variant-glass-tertiary hover:variant-ghost-tertiary transition py-1 px-2"
|
|
title={`Tag: ${tag.trim()}`}
|
|
>
|
|
{tag.trim()}
|
|
</span>
|
|
{/each}
|
|
</div>
|
|
{/if}
|
|
|
|
<!-- Category code for journal entry -->
|
|
{#if journals_journal_entry_obj.category_code}
|
|
<!-- When clicked, this will filter by the category code. -->
|
|
<button
|
|
type="button"
|
|
onclick={() => {
|
|
// WARNING: This will cause pages to reset if the journal entry list is being filtered by category. This is a bug that should be fixed.
|
|
if ($journals_loc.filter__category_code == journals_journal_entry_obj.category_code) {
|
|
$journals_loc.filter__category_code = null;
|
|
} else {
|
|
$journals_loc.filter__category_code = journals_journal_entry_obj.category_code;
|
|
// We also want to set the category code used when creating a new journal entry.
|
|
$journals_loc.qry__category_code = journals_journal_entry_obj.category_code;
|
|
}
|
|
$journals_trig.journal_entry_li = true;
|
|
if (log_lvl) {
|
|
console.log('$journals_loc.filter__category_code', $journals_loc.filter__category_code);
|
|
}
|
|
}}
|
|
class:bg-green-100={$journals_loc.filter__category_code == journals_journal_entry_obj.category_code}
|
|
class="btn btn-sm variant-outline-secondary hover:variant-filled-secondary transition py-1 px-2"
|
|
title={`Filter by category: ${journals_journal_entry_obj.category_code}`}
|
|
>
|
|
<Shapes class="mx-1 inline-block"/>
|
|
{journals_journal_entry_obj.category_code ?? '-- no category --'}
|
|
</button>
|
|
{/if}
|
|
|
|
<a
|
|
href="/journals/{journals_journal_entry_obj?.journal_id}/entry/{journals_journal_entry_obj?.journal_entry_id}"
|
|
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"/>
|
|
<span class="hidden md:inline">
|
|
View
|
|
</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 || (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
|
|
text-wrap text-sm font-mono whitespace-pre-wrap
|
|
transition-all
|
|
delay-1000 hover:delay-1000 active:delay-100
|
|
duration-1000 hover:duration-200 active:duration-200
|
|
ease-in-out
|
|
active:z-10
|
|
hover:bg-blue-100 hover:border-blue-500 dark:hover:border-blue-500
|
|
overflow-scroll
|
|
{$journals_slct.journal_obj.cfg_json.entry_li_max_height ? `${$journals_slct.journal_obj.cfg_json.entry_li_max_height}` : ''}
|
|
|
|
{$journals_slct.journal_obj.cfg_json.entry_li_click_max_height ? `${$journals_slct.journal_obj.cfg_json.entry_li_click_max_height}` : ''}
|
|
|
|
{$journals_slct.journal_obj.cfg_json.entry_li_hover_max_height ? `${$journals_slct.journal_obj.cfg_json.entry_li_hover_max_height}` : ''}
|
|
"
|
|
>
|
|
{@html journals_journal_entry_obj.content}
|
|
</div>
|
|
|
|
<!-- This needs to remain hidden for the copy function to work and us not seeing the rendered HTML version. -->
|
|
<article
|
|
class="prose hidden"
|
|
id="rendered_journal_entry_content_{journals_journal_entry_obj.journal_entry_id}">
|
|
{@html journals_journal_entry_obj?.content_md_html}
|
|
</article>
|
|
{/if}
|
|
|
|
<!-- <div class="ae_options flex flex-row flex-wrap gap-2 items-center justify-center"> -->
|
|
|
|
<!-- <a
|
|
href="/journals/{journals_journal_entry_obj?.journal_id}/entry/{journals_journal_entry_obj?.journal_entry_id}"
|
|
class="btn btn-secondary btn-md variant-ghost-primary hover:variant-filled-primary transition"
|
|
title={`View: ${journals_journal_entry_obj?.name}`}
|
|
>
|
|
<NotebookText class="m-1"/> View
|
|
</a> -->
|
|
|
|
<!-- {#if $ae_loc.trusted_access && $ae_loc.edit_mode}
|
|
<button
|
|
type="button"
|
|
disabled={!$ae_loc.trusted_access}
|
|
onclick={() => {
|
|
$journals_slct.journal_entry_id = journals_journal_entry_obj.journal_entry_id;
|
|
$journals_slct.journal_entry_obj = journals_journal_entry_obj;
|
|
|
|
$journals_sess.show__modal_view__journal_entry_id = false;
|
|
$journals_sess.show__modal_edit__journal_entry_id = $journals_slct.journal_entry_id;
|
|
}}
|
|
class="novi_btn btn btn-sm variant-glass-warning hover:variant-filled-warning transition"
|
|
title={`Edit journal entry: ${journals_journal_entry_obj?.name}`}
|
|
>
|
|
<span class="fas fa-edit m-1"></span> Edit
|
|
</button>
|
|
{/if} -->
|
|
<!-- </div> -->
|
|
|
|
<section
|
|
class:hidden={!journals_journal_entry_obj?.original_datetime && !journals_journal_entry_obj?.original_timezone}
|
|
class="ae_section journal_entry__entry"
|
|
>
|
|
<!-- {#if journals_journal_entry_obj?.description}
|
|
<div
|
|
class="journal_entry__description ae_description"
|
|
>
|
|
<div class="ae_label journal_entry__description text-sm">Description:</div>
|
|
<div class="ae_value journal_entry__description">
|
|
{@html journals_journal_entry_obj?.description}
|
|
</div>
|
|
</div>
|
|
{/if} -->
|
|
|
|
<!-- {#if journals_journal_entry_obj?.entry_html}
|
|
<div
|
|
class="journal_entry__entry_html ae_entry_html"
|
|
>
|
|
<div class="ae_label journal_entry__entry_html text-sm">Content:</div>
|
|
<div class="ae_value journal_entry__entry_html">
|
|
{@html journals_journal_entry_obj?.entry_html}
|
|
</div>
|
|
</div>
|
|
{/if} -->
|
|
|
|
<div
|
|
class="ae_group"
|
|
class:hidden={!journals_journal_entry_obj?.original_datetime && !journals_journal_entry_obj?.original_timezone}
|
|
>
|
|
<span class="ae_label text-sm">Original date/time:</span>
|
|
{#if journals_journal_entry_obj.original_datetime}
|
|
<span class="ae_value ae_prop prop_original_datetime font-semibold">{ae_util.iso_datetime_formatter(journals_journal_entry_obj.original_datetime, 'datetime_12_long')}</span>
|
|
{/if}
|
|
{#if journals_journal_entry_obj.original_timezone}
|
|
<span class="ae_label text-sm">Timezone:</span>
|
|
<span class="ae_value font-semibold">{journals_journal_entry_obj.original_timezone}</span>
|
|
{/if}
|
|
</div>
|
|
|
|
</section>
|
|
|
|
|
|
<section
|
|
class="ae_meta mt-2 flex flex-col sm:flex-row gap-2 items-center justify-center text-xs text-gray-500"
|
|
>
|
|
<!-- <span
|
|
class="journal_entry__journal_entry_type"
|
|
class:hidden={!journals_journal_entry_obj.journal_entry_type}
|
|
>
|
|
Type: {journals_journal_entry_obj.journal_entry_type}
|
|
</span> -->
|
|
<span
|
|
class:hidden={!$ae_loc.trusted_access || !$ae_loc.edit_mode}
|
|
class="flex flex-row gap-1 items-center justify-center"
|
|
>
|
|
<span
|
|
class="journal_entry__created_on"
|
|
>
|
|
Created:
|
|
{ae_util.iso_datetime_formatter(journals_journal_entry_obj.created_on, 'datetime_12_long')}
|
|
</span>
|
|
<span
|
|
class="journal_entry__updated_on"
|
|
class:hidden={!journals_journal_entry_obj.updated_on}
|
|
>
|
|
Last update:
|
|
{ae_util.iso_datetime_formatter(journals_journal_entry_obj.updated_on, 'datetime_12_long')}
|
|
</span>
|
|
</span>
|
|
|
|
<!-- Set/unset hide (boolean) -->
|
|
<button
|
|
type="button"
|
|
onclick={() => {
|
|
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(() => {
|
|
// 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:hidden={!$ae_loc.edit_mode}
|
|
class="btn btn-sm variant-soft-surface hover:variant-filled-warning transition py-1 px-2"
|
|
title={`Set entry as ${journals_journal_entry_obj.hide ? 'visible' : 'hidden'}`}
|
|
>
|
|
{#if journals_journal_entry_obj.hide}
|
|
<EyeOff strokeWidth="1" color="hsla( 0, 100%, 50%, .5)"
|
|
class="inline-block" />
|
|
<span class="hidden md:inline">Hidden</span>
|
|
{:else}
|
|
<Eye strokeWidth="2.5" color="hsla( 120, 100%, 25%, .5)"
|
|
class="inline-block" />
|
|
<span class="hidden lg:inline">Visible</span>
|
|
{/if}
|
|
</button>
|
|
|
|
|
|
</section>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
{/each}
|
|
|
|
<!-- 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 ?? tmp_entry_obj?.created_on} ({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={async () => {
|
|
|
|
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,
|
|
};
|
|
let update_result = await 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((result) => {
|
|
// Optionally, you can provide feedback to the user
|
|
// alert('Journal entry updated successfully!');
|
|
return result;
|
|
}).catch((error) => {
|
|
console.error('Error updating journal entry:', error);
|
|
alert('Failed to update journal entry.');
|
|
}).finally(() => {
|
|
|
|
|
|
});
|
|
if (update_result) {
|
|
// alert('Journal entry updated successfully!');
|
|
// Reset the form
|
|
tmp_entry_obj_append_text_header = '';
|
|
tmp_entry_obj_append_text = '';
|
|
tmp_entry_obj_changed = false;
|
|
$journals_sess.show__modal_append__journal_entry_id = false;
|
|
} else {
|
|
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>
|
|
{/if}
|
|
</section>
|
|
<!-- {/if} -->
|