Progress on moving must buttons and secondary things to the Journal Entry menu.

This commit is contained in:
Scott Idem
2025-05-06 18:17:39 -04:00
parent 13b8255055
commit 89822ef540

View File

@@ -51,6 +51,9 @@ let ae_promises: key_val = $state({});
// let ae_trigger: any = null;
// let ae_triggers: key_val = {};
let show_menu: boolean = $state(false);
// let orig_entry_obj: key_val = $state({});
let orig_entry_obj: key_val|null = $state({});
let tmp_entry_obj_changed: boolean = $state(false);
@@ -168,6 +171,7 @@ async function update_journal_entry() {
history: tmp_entry_obj?.history,
history_encrypted: null, // This should only be generated below.
sort: tmp_entry_obj?.sort,
group: tmp_entry_obj?.group,
archive_on: tmp_entry_obj?.archive_on,
name: tmp_entry_obj?.name,
@@ -611,7 +615,7 @@ function handle_cut_string(old_string: string) {
<header class="ae_header journal_entry__header flex flex-row flex-wrap gap-2 items-center justify-between w-full">
<div class="flex flex-row flex-wrap gap-2 items-center justify-start">
<div class="flex-grow flex flex-row flex-wrap gap-2 items-center justify-start outline">
<!-- Toggle edit for journal entry -->
<button
type="button"
@@ -670,130 +674,10 @@ function handle_cut_string(old_string: string) {
</span>
</h2>
<span class="flex flex-row flex-wrap gap-2 items-center justify-start">
<!-- Button to copy the Markdown version -->
<button
type="button"
onclick={() => {
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="btn btn-sm p-1 variant-soft-secondary *:hover:inline lg:text-xs"
title="Copy the markdown content"
>
<Copy size="1em" />
<RemoveFormatting size="2em" />
<span class="hidden">
Copy Plaintext Markdown
</span>
</button>
<!-- Button to copy the HTML version -->
<button
type="button"
onclick={() => {
// Copy the HTML content to clipboard
const htmlContent = $lq__journal_entry_obj?.content_md_html || '';
navigator.clipboard.writeText(htmlContent).then(() => {
alert('HTML content copied to clipboard!');
}).catch((error) => {
console.error('Failed to copy HTML content:', error);
alert('Failed to copy HTML content.');
});
}}
class="btn btn-sm p-1 variant-soft-secondary *:hover:inline lg:text-xs"
title="Copy the HTML content"
>
<Copy size="1em" />
<CodeXml size="2em" />
<span class="hidden">
Copy HTML
</span>
</button>
<!-- Button to copy the rich text (rendered HTML) version -->
<button
type="button"
onclick={async () => {
const element = document.getElementById(`rendered_journal_entry_content_${$lq__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="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="2em" />
<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: $lq__journal_entry_obj?.code,
category_code: $lq__journal_entry_obj?.category_code,
name: $lq__journal_entry_obj?.name,
short_name: $lq__journal_entry_obj?.short_name,
content: $lq__journal_entry_obj?.content,
description: $lq__journal_entry_obj?.description,
tags: $lq__journal_entry_obj?.tags,
};
journals_func.create_ae_obj__journal_entry({
api_cfg: $ae_api,
journal_id: $lq__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="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="2em" />
<span class="hidden md:inline">Clone</span>
</button>
</span>
</div>
<div class="flex flex-row flex-wrap gap-2 items-center justify-end">
<div class="flex-grow flex flex-row flex-wrap gap-2 items-center justify-end">
<div class="flex flex-row flex-wrap gap-1 items-center justify-center">
<!-- Tags for journal entry. Comma delimited list. -->
{#if $journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id]}
@@ -901,9 +785,370 @@ function handle_cut_string(old_string: string) {
</div>
<section class="relative">
<!-- Menu Button -->
<button
type="button"
onclick={() => (show_menu = !show_menu)}
class="btn variant-outline-secondary hover:variant-filled-secondary transition py-1 px-2"
title="Toggle menu"
>
<Menu size="1.5em" class="inline-block" />
Menu
</button>
<!-- Menu -->
{#if show_menu}
<div
class="absolute top-12 right-0 bg-white dark:bg-gray-800 shadow-lg rounded-lg p-4 z-50 w-80"
>
<!-- Copy and Clone Buttons -->
<div>
<!-- Button to copy the Markdown version -->
<button
type="button"
onclick={() => {
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="btn btn-sm w-full mb-2 p-1 variant-soft-secondary *:hover:inline lg:text-xs"
title="Copy the markdown content"
>
<Copy size="1em" />
<RemoveFormatting size="2em" />
<span class="hidden">
Copy Plaintext Markdown
</span>
</button>
<!-- Button to copy the HTML version -->
<button
type="button"
onclick={() => {
// Copy the HTML content to clipboard
const htmlContent = $lq__journal_entry_obj?.content_md_html || '';
navigator.clipboard.writeText(htmlContent).then(() => {
alert('HTML content copied to clipboard!');
}).catch((error) => {
console.error('Failed to copy HTML content:', error);
alert('Failed to copy HTML content.');
});
}}
class="btn btn-sm w-full mb-2 p-1 variant-soft-secondary *:hover:inline lg:text-xs"
title="Copy the HTML content"
>
<Copy size="1em" />
<CodeXml size="2em" />
<span class="hidden">
Copy HTML
</span>
</button>
<!-- Button to copy the rich text (rendered HTML) version -->
<button
type="button"
onclick={async () => {
const element = document.getElementById(`rendered_journal_entry_content_${$lq__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="btn btn-sm w-full mb-2 p-1 variant-soft-secondary *:hover:inline lg:text-xs"
title="Copy the rich text (rendered HTML) content"
>
<Copy size="1em" />
<TypeOutline size="2em" />
<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: $lq__journal_entry_obj?.code,
category_code: $lq__journal_entry_obj?.category_code,
name: $lq__journal_entry_obj?.name,
short_name: $lq__journal_entry_obj?.short_name,
content: $lq__journal_entry_obj?.content,
description: $lq__journal_entry_obj?.description,
tags: $lq__journal_entry_obj?.tags,
};
journals_func.create_ae_obj__journal_entry({
api_cfg: $ae_api,
journal_id: $lq__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="btn btn-sm w-full mb-2 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="2em" />
<span class="hidden md:inline">Clone Entry</span>
</button>
</div>
<div class="divider my-2"></div>
<!-- Core Object Properties -->
<div>
<!-- Set/unset priority (boolean) -->
<button
type="button"
onclick={() => {
tmp_entry_obj.priority = !$lq__journal_entry_obj?.priority;
update_journal_entry();
}}
class="btn w-full mb-2 variant-soft-tertiary transition hover:variant-filled-tertiary"
title="Toggle priority of this journal entry"
>
{#if $lq__journal_entry_obj?.priority}
<Flag strokeWidth="2.5" color="green" class="inline-block" />
{:else}
<FlagOff strokeWidth="1" color="gray" class="inline-block" />
{/if}
<span class="hidden lg:inline">
Priority
</span>
</button>
<!-- Set sort order (number) -->
<span
class:hidden={!$ae_loc.edit_mode}
class="w-full mb-2 flex flex-row flex-wrap items-center justify-center border border-gray-300 rounded-lg">
<button
type="button"
onclick={() => {
console.log('Incrementing sort order');
tmp_entry_obj.sort = $lq__journal_entry_obj?.sort ? $lq__journal_entry_obj?.sort + 1 : 1;
console.log('Incremented sort order:', tmp_entry_obj.sort);
update_journal_entry();
}}
class="btn-icon-sm variant-soft-tertiary transition hover:variant-filled-tertiary"
title="Increment sort order of this journal entry"
>
<Plus strokeWidth="2.5" color="blue" />
</button>
<span class="mx-1">
{#if $lq__journal_entry_obj?.sort}
{$lq__journal_entry_obj.sort}
{:else}
<!-- <ArrowDown01 /> -->
<ArrowDown10 />
{/if}
</span>
<button
type="button"
onclick={() => {
console.log('Decrementing sort order');
tmp_entry_obj.sort = $lq__journal_entry_obj?.sort ? $lq__journal_entry_obj?.sort - 1 : 0;
console.log('Decremented sort order:', tmp_entry_obj.sort);
update_journal_entry();
}}
class="btn-icon-sm variant-soft-tertiary transition hover:variant-filled-tertiary"
title="Decrement sort order of this journal entry"
>
<Minus strokeWidth="2.5" color="blue" />
</button>
</span>
<!-- Set group (string) -->
<input
type="text"
bind:value={tmp_entry_obj.group}
placeholder="Group"
onchange={() => {
update_journal_entry();
}}
class:hidden={!$ae_loc.edit_mode}
class="input input-sm input-bordered w-full mb-2"
title="Set group (for sorting) of this journal entry"
/>
<!-- Set archive datetime (string) -->
<span class="w-full mb-2 flex flex-row flex-wrap items-center justify-center border border-gray-200 rounded-lg">
<input
type="datetime-local"
bind:value={tmp_entry_obj.archive_on}
placeholder="Archive On"
onchange={() => {
update_journal_entry();
}}
class:hidden={!$ae_loc.edit_mode}
class="input input-sm input-bordered w-auto border-none"
title="Set archive on datetime for archiving this journal entry"
/>
{#if $lq__journal_entry_obj?.archive_on}
<!-- Button to clear the datetime -->
<button
type="button"
onclick={() => {
tmp_entry_obj.archive_on = null;
update_journal_entry();
}}
class:hidden={!$ae_loc.edit_mode}
class="btn btn-icon btn-icon-sm variant-glass-warning hover:variant-filled-warning transition *:hover:inline"
title="Clear the archive on datetime for this journal entry"
>
<X strokeWidth="2.5" color="red" />
<!-- <span class="hidden">Clear Archive</span> -->
</button>
{:else}
<!-- Button to set the datetime to now -->
<button
type="button"
onclick={() => {
// tmp_entry_obj.archive_on = new Date().toISOString();
// console.log('Archive on datetime set to now:', tmp_entry_obj.archive_on);
tmp_entry_obj = {
...tmp_entry_obj,
archive_on: new Date().toISOString()
};
console.log('Archive on datetime set to now:', tmp_entry_obj.archive_on);
update_journal_entry();
}}
class:hidden={!$ae_loc.edit_mode}
class="btn btn-icon btn-icon-sm variant-glass-warning hover:variant-filled-warning transition *:hover:inline"
title="Set the archive on datetime for this journal entry"
>
<Clock strokeWidth="2.5" color="blue" />
<!-- <span class="hidden">Set Archive</span> -->
</button>
{/if}
</span>
<!-- Set/unset hide (boolean) -->
<button
type="button"
onclick={() => {
tmp_entry_obj.hide = !$lq__journal_entry_obj?.hide;
update_journal_entry();
}}
class="btn btn-sm md:btn-md w-full mb-2 variant-soft-warning hover:variant-filled-warning transition"
title="Toggle visibility of this journal entry"
>
{#if $lq__journal_entry_obj?.hide}
<EyeOff strokeWidth="1" color="red" class="inline-block" />
<span class="hidden md:inline">Hidden</span>
{:else}
<Eye strokeWidth="2.5" color="green" class="inline-block" />
<span class="hidden md:inline">Visible</span>
{/if}
</button>
<!-- Set/unset enable (boolean) -->
<button
type="button"
onclick={() => {
tmp_entry_obj.enable = !$lq__journal_entry_obj?.enable;
update_journal_entry();
}}
class:hidden={!$ae_loc.administrator_access || !$ae_loc.edit_mode}
class="btn btn-sm md:btn-md w-full mb-2 variant-soft-error hover:variant-filled-error transition"
title="Toggle enable status of this journal entry"
>
{#if $lq__journal_entry_obj?.enable}
<ShieldCheck strokeWidth="2.5" color="green" class="inline-block" />
<span class="hidden md:inline">Enabled</span>
{:else}
<ShieldMinus strokeWidth="1" color="red" class="inline-block" />
<span class="hidden md:inline">Disabled</span>
{/if}
</button>
<!-- Delete journal entry -->
<button
type="button"
onclick={() => {
if (confirm(`Are you sure you want to delete this journal entry?`)) {
let delete_method = 'disable';
if ($ae_loc.administrator_access && $ae_loc.edit_mode) {
delete_method = 'delete';
}
journals_func.delete_ae_obj_id__journal_entry({
api_cfg: $ae_api,
journal_entry_id: $lq__journal_entry_obj?.journal_entry_id,
method: delete_method, // 'delete', 'disable', 'hide'
log_lvl: log_lvl
}).then(() => {
// Optionally, you can provide feedback to the user
alert('Journal entry deleted successfully!');
}).catch((error) => {
console.error('Error deleting journal entry:', error);
alert('Failed to delete journal entry.');
}).finally(() => {
$journals_slct.journal_id = null;
$journals_slct.journal_obj = null;
goto(`/journals/${$lq__journal_entry_obj?.journal_id}`);
});
}
}}
class:hidden={!$ae_loc.edit_mode}
class="btn btn-sm md:btn-md w-full mb-2 variant-soft-error hover:variant-filled-error transition"
title="Delete this journal entry"
>
{#if ($ae_loc.administrator_access && $ae_loc.edit_mode)}
<FileX strokeWidth="2.5" color="red" class="inline-block" />
<span class="hidden md:inline">Delete</span>
{:else}
<Trash2 strokeWidth="2.5" color="orange" class="inline-block" />
<span class="hidden md:inline">Remove</span>
{/if}
</button>
</div>
</div>
{/if}
</section>
</div>
</header>
<section
class="flex flex-row flex-wrap gap-1 items-center justify-evenly w-full max-w-sm "
>