Now with a description and basic color scheme. Saving before making some more changes.
This commit is contained in:
@@ -2,6 +2,7 @@ import type { key_val } from '$lib/ae_stores';
|
|||||||
import { api } from '$lib/api';
|
import { api } from '$lib/api';
|
||||||
|
|
||||||
import { db_journals } from "$lib/ae_journals/db_journals";
|
import { db_journals } from "$lib/ae_journals/db_journals";
|
||||||
|
import { marked } from 'marked';
|
||||||
|
|
||||||
import { load_ae_obj_li__journal_entry } from "$lib/ae_journals/ae_journals__journal_entry";
|
import { load_ae_obj_li__journal_entry } from "$lib/ae_journals/ae_journals__journal_entry";
|
||||||
|
|
||||||
@@ -536,6 +537,12 @@ export function db_save_ae_obj_li__journal(
|
|||||||
console.log(`ae_obj ${obj_type}:`, obj);
|
console.log(`ae_obj ${obj_type}:`, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let description = obj.description ?? '';
|
||||||
|
// remove the most common zerowidth characters from the start of the file
|
||||||
|
let description_cleaned: string = description.replace(/^[\u200B\u200C\u200D\u200E\u200F\uFEFF]/,"");
|
||||||
|
let description_md_html: null|string = await marked.parse(description_cleaned ?? '') ?? null;
|
||||||
|
// let description_md_html_alt: null|string = await marked.parse(description_cleaned ?? '', { gfm: false }) ?? null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const id_random = await db_journals.journal.put({
|
const id_random = await db_journals.journal.put({
|
||||||
id: obj.journal_id_random,
|
id: obj.journal_id_random,
|
||||||
@@ -557,6 +564,7 @@ export function db_save_ae_obj_li__journal(
|
|||||||
outline: obj.outline,
|
outline: obj.outline,
|
||||||
|
|
||||||
description: obj.description,
|
description: obj.description,
|
||||||
|
description_md_html: description_md_html, // Use the markdown parser to generate HTML
|
||||||
description_html: obj.description_html,
|
description_html: obj.description_html,
|
||||||
description_json: obj.description_json,
|
description_json: obj.description_json,
|
||||||
|
|
||||||
|
|||||||
@@ -41,6 +41,8 @@ export interface Journal {
|
|||||||
outline?: null|string; // LLM (AI) generated outline...???
|
outline?: null|string; // LLM (AI) generated outline...???
|
||||||
|
|
||||||
description?: null|string;
|
description?: null|string;
|
||||||
|
description_md_html?: null|string; // Markdown converted to HTML based on description. Uses marked or similar library for conversion.
|
||||||
|
description_md_html_alt?: null|string; // Markdown converted to HTML based on description. Uses marked or similar library for conversion.
|
||||||
description_html?: null|string;
|
description_html?: null|string;
|
||||||
description_json?: null|string;
|
description_json?: null|string;
|
||||||
|
|
||||||
@@ -182,8 +184,8 @@ export interface Journal_Entry {
|
|||||||
// description?: null|string; // This is the description of the journal entry
|
// description?: null|string; // This is the description of the journal entry
|
||||||
|
|
||||||
content?: null|string;
|
content?: null|string;
|
||||||
content_md_html?: null|string; // Markdown converted to HTML based on content
|
content_md_html?: null|string; // Markdown converted to HTML based on content. Uses marked or similar library for conversion.
|
||||||
content_md_html_alt?: null|string; // Markdown converted to HTML based on content
|
content_md_html_alt?: null|string; // Markdown converted to HTML based on content. Uses marked or similar library for conversion.
|
||||||
content_html?: null|string;
|
content_html?: null|string;
|
||||||
content_json?: null|string;
|
content_json?: null|string;
|
||||||
|
|
||||||
|
|||||||
@@ -408,8 +408,26 @@ $effect(() => {
|
|||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onclick={() => {
|
onclick={() => {
|
||||||
|
// Clear the localStorage and sessionStorage, then reload the page.
|
||||||
|
indexedDB.deleteDatabase('ae_core_db');
|
||||||
|
indexedDB.deleteDatabase('ae_archives_db');
|
||||||
|
indexedDB.deleteDatabase('ae_events_db');
|
||||||
|
indexedDB.deleteDatabase('ae_journals_db');
|
||||||
|
indexedDB.deleteDatabase('ae_posts_db');
|
||||||
|
window.location.reload();
|
||||||
|
}}
|
||||||
|
ondblclick={() => {
|
||||||
|
// Double click to clear all databases and reload the page.
|
||||||
|
indexedDB.deleteDatabase('ae_core_db');
|
||||||
|
indexedDB.deleteDatabase('ae_archives_db');
|
||||||
|
indexedDB.deleteDatabase('ae_events_db');
|
||||||
|
indexedDB.deleteDatabase('ae_journals_db');
|
||||||
|
indexedDB.deleteDatabase('ae_posts_db');
|
||||||
|
|
||||||
|
// Clear localStorage and sessionStorage
|
||||||
localStorage.clear();
|
localStorage.clear();
|
||||||
sessionStorage.clear();
|
sessionStorage.clear();
|
||||||
|
|
||||||
alert('Local and Session Storage cleared. The page should now refresh on its own.');
|
alert('Local and Session Storage cleared. The page should now refresh on its own.');
|
||||||
// window.location.reload({forceGet: true});
|
// window.location.reload({forceGet: true});
|
||||||
// window.location.reload(true);
|
// window.location.reload(true);
|
||||||
|
|||||||
@@ -113,16 +113,12 @@ if (browser) {
|
|||||||
|
|
||||||
onclick={() => {
|
onclick={() => {
|
||||||
// Confirm before clearing
|
// Confirm before clearing
|
||||||
if (!confirm("Are you sure you want to clear all *local* app data and settings? This will also reload the page.")) {
|
if (!confirm("Are you sure you want to clear IndexedDB databases and some caches? This will also reload the page.")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
console.log("Clearing local and session storage, and reloading the page...");
|
|
||||||
|
|
||||||
// Clear the local and session storage. Clearing the localStorage will force it to be re-created.
|
|
||||||
localStorage.clear();
|
|
||||||
sessionStorage.clear();
|
|
||||||
|
|
||||||
// Clear Indexed DB as well
|
// Clear Indexed DB
|
||||||
indexedDB.deleteDatabase('ae_core_db');
|
indexedDB.deleteDatabase('ae_core_db');
|
||||||
indexedDB.deleteDatabase('ae_journals_db');
|
indexedDB.deleteDatabase('ae_journals_db');
|
||||||
|
|
||||||
@@ -133,6 +129,26 @@ if (browser) {
|
|||||||
window.location.reload(true); // true only works with Firefox
|
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.');
|
// alert('Local and Session Storage cleared and Indexed DBs deleted. You will probably want to refresh the page.');
|
||||||
}}
|
}}
|
||||||
|
ondblclick={() => {
|
||||||
|
// Confirm before clearing
|
||||||
|
if (!confirm("Are you sure you want to clear all *local* app data and settings? This will also reload the page.")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
console.log("Clearing IndexedDB, localStorage, sessionStorage, and reloading the page...");
|
||||||
|
|
||||||
|
// Clear Indexed DB
|
||||||
|
indexedDB.deleteDatabase('ae_core_db');
|
||||||
|
indexedDB.deleteDatabase('ae_journals_db');
|
||||||
|
|
||||||
|
// Clear localStorage and sessionStorage
|
||||||
|
// Clearing the localStorage will force it to be re-created.
|
||||||
|
localStorage.clear();
|
||||||
|
sessionStorage.clear();
|
||||||
|
|
||||||
|
goto('/', {invalidateAll: true});
|
||||||
|
|
||||||
|
window.location.reload(true);
|
||||||
|
}}
|
||||||
class="btn btn-sm variant-ghost-surface hover:variant-filled-warning"
|
class="btn btn-sm variant-ghost-surface hover:variant-filled-warning"
|
||||||
title="Clear App Data & Settings - Reload: Clear the browser storage for this site"
|
title="Clear App Data & Settings - Reload: Clear the browser storage for this site"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ async function handle_update_journal() {
|
|||||||
let data_kv = {
|
let data_kv = {
|
||||||
// account: $slct.account_id,
|
// account: $slct.account_id,
|
||||||
name: $journals_slct.tmp_journal_obj.name,
|
name: $journals_slct.tmp_journal_obj.name,
|
||||||
|
description: $journals_slct.tmp_journal_obj.description ?? '', // Ensure description is at least an empty string
|
||||||
type_code: $journals_slct.tmp_journal_obj.type_code,
|
type_code: $journals_slct.tmp_journal_obj.type_code,
|
||||||
passcode: $journals_slct.tmp_journal_obj.passcode,
|
passcode: $journals_slct.tmp_journal_obj.passcode,
|
||||||
passcode_timeout: $journals_slct.tmp_journal_obj.passcode_timeout,
|
passcode_timeout: $journals_slct.tmp_journal_obj.passcode_timeout,
|
||||||
@@ -171,6 +172,7 @@ async function handle_update_journal() {
|
|||||||
onclick={() => {
|
onclick={() => {
|
||||||
$journals_slct.tmp_journal_obj = {
|
$journals_slct.tmp_journal_obj = {
|
||||||
name: $lq__journal_obj?.name,
|
name: $lq__journal_obj?.name,
|
||||||
|
description: $lq__journal_obj?.description,
|
||||||
type_code: $lq__journal_obj?.type_code,
|
type_code: $lq__journal_obj?.type_code,
|
||||||
passcode: $lq__journal_obj?.passcode,
|
passcode: $lq__journal_obj?.passcode,
|
||||||
passcode_timeout: $lq__journal_obj?.passcode_timeout,
|
passcode_timeout: $lq__journal_obj?.passcode_timeout,
|
||||||
@@ -258,7 +260,10 @@ async function handle_update_journal() {
|
|||||||
"
|
"
|
||||||
bind:value={$journals_loc.qry__category_code}
|
bind:value={$journals_loc.qry__category_code}
|
||||||
onchange={(event) => {
|
onchange={(event) => {
|
||||||
|
// 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.
|
||||||
$journals_loc.qry__category_code = event.target.value;
|
$journals_loc.qry__category_code = event.target.value;
|
||||||
|
$journals_loc.filter__category_code = event.target.value;
|
||||||
|
$journals_trig.journal_entry_li = true;
|
||||||
console.log('Selected category:', $journals_loc.qry__category_code);
|
console.log('Selected category:', $journals_loc.qry__category_code);
|
||||||
}}
|
}}
|
||||||
title="Select a category for the new journal entry"
|
title="Select a category for the new journal entry"
|
||||||
@@ -297,6 +302,15 @@ async function handle_update_journal() {
|
|||||||
<!-- <h3 class="font-bold text-lg">Edit Journal</h3> -->
|
<!-- <h3 class="font-bold text-lg">Edit Journal</h3> -->
|
||||||
<div class="py-4">
|
<div class="py-4">
|
||||||
<input type="text" placeholder="Journal Name" bind:value={$journals_slct.tmp_journal_obj.name} class="input input-bordered w-full mb-2" />
|
<input type="text" placeholder="Journal Name" bind:value={$journals_slct.tmp_journal_obj.name} class="input input-bordered w-full mb-2" />
|
||||||
|
|
||||||
|
<!-- Journal Description (Markdown) -->
|
||||||
|
<textarea
|
||||||
|
placeholder="Journal Description (Markdown format)"
|
||||||
|
bind:value={$journals_slct.tmp_journal_obj.description}
|
||||||
|
class="input input-bordered w-full mb-2 h-32 resize-none"
|
||||||
|
title="Description of the journal (supports Markdown)"
|
||||||
|
></textarea>
|
||||||
|
|
||||||
<input type="text" placeholder="Journal Type" bind:value={$journals_slct.tmp_journal_obj.type_code} class="input input-bordered w-full mb-2" />
|
<input type="text" placeholder="Journal Type" bind:value={$journals_slct.tmp_journal_obj.type_code} class="input input-bordered w-full mb-2" />
|
||||||
|
|
||||||
<!-- input for passcode -->
|
<!-- input for passcode -->
|
||||||
@@ -393,7 +407,34 @@ async function handle_update_journal() {
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Select color scheme for the journal entries -->
|
||||||
|
<!-- Should select from the common Tailwind CSS options. Examples: slate, blue, gray, green, orange, red, yellow, etc. -->
|
||||||
|
<!-- Saves to cfg_json.color_scheme -->
|
||||||
|
<div>
|
||||||
|
<span class="text-sm text-gray-500 hidden sm:inline">
|
||||||
|
Color Scheme:
|
||||||
|
</span>
|
||||||
|
<select
|
||||||
|
class="btn btn-sm variant-ghost-surface hover:variant-filled-surface transition text-xs w-full mb-2 max-w-96"
|
||||||
|
bind:value={$journals_slct.tmp_journal_obj.cfg_json.color_scheme}
|
||||||
|
title="Select color scheme for journal entries"
|
||||||
|
onchange={(event) => {
|
||||||
|
$journals_slct.tmp_journal_obj.cfg_json.color_scheme = event.target.value;
|
||||||
|
console.log('Selected color scheme:', $journals_slct.tmp_journal_obj.cfg_json.color_scheme);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<option value="">Default (auto)</option>
|
||||||
|
<option value="slate">Slate</option>
|
||||||
|
<option value="gray">Gray</option>
|
||||||
|
<option value="blue">Blue</option>
|
||||||
|
<option value="green">Green</option>
|
||||||
|
<option value="orange">Orange</option>
|
||||||
|
<option value="red">Red</option>
|
||||||
|
<option value="yellow">Yellow</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- JSON configuration editor for advanced users -->
|
||||||
<!-- textarea for json_cfg editing -->
|
<!-- textarea for json_cfg editing -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -235,6 +235,7 @@ let tmp_entry_obj: key_val = $state({});
|
|||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onclick={() => {
|
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) {
|
if ($journals_loc.filter__category_code == journals_journal_entry_obj.category_code) {
|
||||||
$journals_loc.filter__category_code = null;
|
$journals_loc.filter__category_code = null;
|
||||||
} else {
|
} else {
|
||||||
@@ -247,6 +248,7 @@ let tmp_entry_obj: key_val = $state({});
|
|||||||
console.log('$journals_loc.filter__category_code', $journals_loc.filter__category_code);
|
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"
|
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}`}
|
title={`Filter by category: ${journals_journal_entry_obj.category_code}`}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -46,6 +46,36 @@ let { log_lvl = 0, lq__journal_obj, lq__journal_entry_obj_li }: Props = $props()
|
|||||||
</h2>
|
</h2>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
<!-- Show Journal description -->
|
||||||
|
<!-- class:bg-green-100={$lq__journal_obj?.cfg_json.color_scheme ?? 'green'} -->
|
||||||
|
<div>
|
||||||
|
{#if $lq__journal_obj?.description}
|
||||||
|
<div
|
||||||
|
|
||||||
|
class="
|
||||||
|
prose
|
||||||
|
space-y-1
|
||||||
|
journal__description
|
||||||
|
p-2
|
||||||
|
font-mono
|
||||||
|
bg-{$lq__journal_obj?.cfg_json.color_scheme}-100 text-gray-900
|
||||||
|
dark:bg-blue-900 dark:text-gray-100
|
||||||
|
shadow-md rounded-lg
|
||||||
|
text-sm font-normal text-wrap whitespace-pre-wrap word-break
|
||||||
|
max-w-screen-md
|
||||||
|
|
||||||
|
prose-h1:underline prose-h1:decoration-double
|
||||||
|
prose-h2:underline
|
||||||
|
prose-h1:text-2xl prose-h2:text-xl prose-h3:text-lg
|
||||||
|
prose-h1:m-0 prose-h2:m-0 prose-h3:m-0 prose-h4:m-0 prose-h5:m-0 prose-h6:m-0
|
||||||
|
prose-li:m-0 prose-li:p-0 prose-li:line-height-none
|
||||||
|
"
|
||||||
|
>
|
||||||
|
{@html $lq__journal_obj.description_md_html}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user