Lots of work on the Journals
This commit is contained in:
13
package-lock.json
generated
13
package-lock.json
generated
@@ -20,6 +20,7 @@
|
|||||||
"dexie": "^4.0.1-beta.14",
|
"dexie": "^4.0.1-beta.14",
|
||||||
"flowbite-svelte": "^0.48.00",
|
"flowbite-svelte": "^0.48.00",
|
||||||
"html5-qrcode": "^2.3.8",
|
"html5-qrcode": "^2.3.8",
|
||||||
|
"marked": "^15.0.7",
|
||||||
"shadcn-svelte": "^0.14.0"
|
"shadcn-svelte": "^0.14.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@@ -4703,6 +4704,18 @@
|
|||||||
"markdown-it": "bin/markdown-it.mjs"
|
"markdown-it": "bin/markdown-it.mjs"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/marked": {
|
||||||
|
"version": "15.0.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/marked/-/marked-15.0.7.tgz",
|
||||||
|
"integrity": "sha512-dgLIeKGLx5FwziAnsk4ONoGwHwGPJzselimvlVskE9XLN4Orv9u2VA3GWw/lYUqjfA0rUT/6fqKwfZJapP9BEg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"bin": {
|
||||||
|
"marked": "bin/marked.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/math-intrinsics": {
|
"node_modules/math-intrinsics": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
|
||||||
|
|||||||
@@ -98,6 +98,7 @@
|
|||||||
"dexie": "^4.0.1-beta.14",
|
"dexie": "^4.0.1-beta.14",
|
||||||
"flowbite-svelte": "^0.48.00",
|
"flowbite-svelte": "^0.48.00",
|
||||||
"html5-qrcode": "^2.3.8",
|
"html5-qrcode": "^2.3.8",
|
||||||
|
"marked": "^15.0.7",
|
||||||
"shadcn-svelte": "^0.14.0"
|
"shadcn-svelte": "^0.14.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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';
|
||||||
|
|
||||||
let ae_promises: key_val = {};
|
let ae_promises: key_val = {};
|
||||||
|
|
||||||
@@ -357,6 +358,7 @@ export async function db_save_ae_obj_li__journal_entry(
|
|||||||
category_code: obj.category_code,
|
category_code: obj.category_code,
|
||||||
type_code: obj.type_code,
|
type_code: obj.type_code,
|
||||||
topic_code: obj.topic_code,
|
topic_code: obj.topic_code,
|
||||||
|
tags: obj.tags,
|
||||||
|
|
||||||
public: obj.public,
|
public: obj.public,
|
||||||
private: obj.private,
|
private: obj.private,
|
||||||
@@ -369,6 +371,7 @@ export async function db_save_ae_obj_li__journal_entry(
|
|||||||
// description: obj.description,
|
// description: obj.description,
|
||||||
|
|
||||||
content: obj.content,
|
content: obj.content,
|
||||||
|
content_md_html: marked.parse(obj.content),
|
||||||
content_html: obj.content_html,
|
content_html: obj.content_html,
|
||||||
content_json: obj.content_json,
|
content_json: obj.content_json,
|
||||||
|
|
||||||
@@ -415,6 +418,12 @@ export async function db_save_ae_obj_li__journal_entry(
|
|||||||
created_on: obj.created_on,
|
created_on: obj.created_on,
|
||||||
updated_on: obj.updated_on,
|
updated_on: obj.updated_on,
|
||||||
|
|
||||||
|
// Generated fields for sorting locally only
|
||||||
|
tmp_sort_1: `${obj.group}_${obj.priority}_${obj.sort}_${obj.updated_on}_${obj.created_on}`,
|
||||||
|
tmp_sort_2: `${obj.group}_${obj.priority}_${obj.sort}_${obj.updated_on ?? obj.created_on}`,
|
||||||
|
// tmp_sort_1: `${obj.original_datetime}_${obj.group}_${obj.priority}_${obj.sort}`,
|
||||||
|
// tmp_sort_2: `${obj.group}_${obj.original_datetime}_${obj.priority}_${obj.sort}`,
|
||||||
|
|
||||||
// Generated fields for sorting locally only
|
// Generated fields for sorting locally only
|
||||||
// tmp_sort_1: `${obj.original_datetime}_${obj.group}_${obj.priority}_${obj.sort}`,
|
// tmp_sort_1: `${obj.original_datetime}_${obj.group}_${obj.priority}_${obj.sort}`,
|
||||||
// tmp_sort_2: `${obj.group}_${obj.original_datetime}_${obj.priority}_${obj.sort}`,
|
// tmp_sort_2: `${obj.group}_${obj.original_datetime}_${obj.priority}_${obj.sort}`,
|
||||||
|
|||||||
@@ -151,6 +151,7 @@ export interface Journal_Entry {
|
|||||||
category_code?: null|string;
|
category_code?: null|string;
|
||||||
topic_code?: null|string;
|
topic_code?: null|string;
|
||||||
type_code?: null|string;
|
type_code?: null|string;
|
||||||
|
tags?: null|string; // Comma separated tags
|
||||||
|
|
||||||
journal_entry_type?: null|string; // This is the type of journal entry
|
journal_entry_type?: null|string; // This is the type of journal entry
|
||||||
|
|
||||||
@@ -170,6 +171,7 @@ 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_html?: null|string;
|
content_html?: null|string;
|
||||||
content_json?: null|string;
|
content_json?: null|string;
|
||||||
|
|
||||||
@@ -211,6 +213,10 @@ export interface Journal_Entry {
|
|||||||
created_on: Date;
|
created_on: Date;
|
||||||
updated_on?: null|Date;
|
updated_on?: null|Date;
|
||||||
|
|
||||||
|
// Generated fields for sorting locally only
|
||||||
|
tmp_sort_1?: null|string;
|
||||||
|
tmp_sort_2?: null|string;
|
||||||
|
|
||||||
// Additional fields for convenience (database views)
|
// Additional fields for convenience (database views)
|
||||||
file_count?: null|number; // Only files directly under a journal
|
file_count?: null|number; // Only files directly under a journal
|
||||||
journal_file_id_li_json?: null|string;
|
journal_file_id_li_json?: null|string;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ let log_lvl: number = 0;
|
|||||||
|
|
||||||
// *** Import Svelte specific
|
// *** Import Svelte specific
|
||||||
import { browser } from '$app/environment';
|
import { browser } from '$app/environment';
|
||||||
|
import { goto } from '$app/navigation';
|
||||||
|
|
||||||
// *** Import other supporting libraries
|
// *** Import other supporting libraries
|
||||||
import { Modal } from 'flowbite-svelte';
|
import { Modal } from 'flowbite-svelte';
|
||||||
@@ -59,12 +60,11 @@ let lq__journal_obj = $derived(liveQuery(async () => {
|
|||||||
return results;
|
return results;
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let force_refresh = false; // Set to true to force a refresh of the data
|
|
||||||
let lq__journal_entry_obj_li = $derived(liveQuery(async () => {
|
let lq__journal_entry_obj_li = $derived(liveQuery(async () => {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`$lq__journal_obj.cfg_json = `, $lq__journal_obj?.cfg_json);
|
console.log(`$lq__journal_obj.cfg_json = `, $lq__journal_obj?.cfg_json);
|
||||||
console.log(`$journals_loc.filter__category_code = `, $journals_loc.filter__category_code);
|
console.log(`$journals_loc.filter__category_code = `, $journals_loc.filter__category_code);
|
||||||
console.log(`force_refresh = `, force_refresh);
|
|
||||||
}
|
}
|
||||||
if ($lq__journal_obj?.cfg_json?.entry_group_sort === 'DESC') {
|
if ($lq__journal_obj?.cfg_json?.entry_group_sort === 'DESC') {
|
||||||
let results = await db_journals.journal_entry
|
let results = await db_journals.journal_entry
|
||||||
@@ -77,24 +77,14 @@ let lq__journal_entry_obj_li = $derived(liveQuery(async () => {
|
|||||||
// .sortBy('title');
|
// .sortBy('title');
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
// } else if (force_refresh) {
|
|
||||||
// force_refresh = false;
|
|
||||||
// console.log(`lq__journal_entry_obj_li - force refresh`);
|
|
||||||
// let results = await db_journals.journal_entry
|
|
||||||
// .where('journal_id')
|
|
||||||
// .equals($journals_slct?.journal_id ?? '') // null or undefined does not reset things like '' does
|
|
||||||
// // .reverse()
|
|
||||||
// .sortBy('updated_on');
|
|
||||||
|
|
||||||
// return results;
|
|
||||||
} else if ($journals_loc.filter__category_code && $journals_loc.filter__category_code.length > 0) {
|
} else if ($journals_loc.filter__category_code && $journals_loc.filter__category_code.length > 0) {
|
||||||
console.log(`lq__journal_entry_obj_li - filtering by category_code: ${$journals_loc.filter__category_code}`);
|
console.log(`lq__journal_entry_obj_li - filtering by category_code: ${$journals_loc.filter__category_code}`);
|
||||||
let results = await db_journals.journal_entry
|
let results = await db_journals.journal_entry
|
||||||
.where('journal_id')
|
.where('journal_id')
|
||||||
.equals($journals_slct?.journal_id ?? '') // null or undefined does not reset things like '' does
|
.equals($journals_slct?.journal_id ?? '') // null or undefined does not reset things like '' does
|
||||||
.and(entry => entry.category_code === $journals_loc.filter__category_code)
|
.and(entry => entry.category_code === $journals_loc.filter__category_code)
|
||||||
// .reverse()
|
.reverse()
|
||||||
.sortBy('updated_on');
|
.sortBy('tmp_sort_1');
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
} else {
|
} else {
|
||||||
@@ -102,33 +92,18 @@ let lq__journal_entry_obj_li = $derived(liveQuery(async () => {
|
|||||||
let results = await db_journals.journal_entry
|
let results = await db_journals.journal_entry
|
||||||
.where('journal_id')
|
.where('journal_id')
|
||||||
.equals($journals_slct?.journal_id ?? '') // null or undefined does not reset things like '' does
|
.equals($journals_slct?.journal_id ?? '') // null or undefined does not reset things like '' does
|
||||||
// .reverse()
|
.reverse()
|
||||||
.sortBy('updated_on');
|
.sortBy('tmp_sort_1');
|
||||||
|
// .sortBy('updated_on');
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// let lq__journal_entry_obj = $derived(liveQuery(async () => {
|
|
||||||
// if (log_lvl) {
|
|
||||||
// console.log(`lq__journal_entry_obj: journal_entry_id = ${$journals_slct?.journal_entry_id}`);
|
|
||||||
// }
|
|
||||||
// if ($journals_slct.journal_entry_id) {
|
|
||||||
// let results = await db_journals.journal_entry
|
|
||||||
// .get($journals_slct.journal_entry_id); // null or undefined does not reset things like '' does
|
|
||||||
|
|
||||||
// return results;
|
|
||||||
// }
|
|
||||||
// // const results = await db_journals.journal_entry
|
|
||||||
// // .get($journals_slct.journal_entry_id); // null or undefined does not reset things like '' does
|
|
||||||
|
|
||||||
// // return results;
|
|
||||||
// }));
|
|
||||||
|
|
||||||
|
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
if ($journals_trig.journal_entry_li) {
|
if ($journals_trig.journal_entry_li) {
|
||||||
$journals_trig.journal_entry_li = false;
|
$journals_trig.journal_entry_li = false;
|
||||||
|
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
@@ -136,30 +111,14 @@ $effect(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($journals_loc.qry__enabled !== 'all' || $journals_loc.qry__hidden !== 'all') {
|
if ($journals_loc.qry__enabled !== 'all' || $journals_loc.qry__hidden !== 'all') {
|
||||||
console.log(`Deleting disabled or hidden journal entry.`);
|
console.log(`Not set to all for enabled or hidden. Clearing all journal entries to be safe.`);
|
||||||
// let results = db_journals.journal_entry
|
|
||||||
// .where('enable')
|
|
||||||
// .notEqual(true)
|
|
||||||
// .delete();
|
|
||||||
let results = db_journals.journal_entry
|
let results = db_journals.journal_entry
|
||||||
.clear();
|
.clear();
|
||||||
console.log(`Deleted ${results} disabled journal entry.`);
|
console.log(`Deleted ${results} disabled journal entry.`);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// if ($journals_loc.qry__hidden !== 'all') {
|
|
||||||
// console.log(`Deleting hidden journal entry.`);
|
|
||||||
// let results = db_journals.journal_entry
|
|
||||||
// .clear();
|
|
||||||
// console.log(`Deleted ${results} hidden journal entry.`);
|
|
||||||
|
|
||||||
// }
|
|
||||||
// let results = db_journals.journal_entry
|
|
||||||
// .where('enable')
|
|
||||||
// .equals('false')
|
|
||||||
// .delete();
|
|
||||||
// console.log(`Deleted ${results} disabled journal entry.`);
|
|
||||||
|
|
||||||
$journals_prom.load__journal_entry_obj_li = journals_func.load_ae_obj_li__journal_entry({
|
$journals_prom.load__journal_entry_obj_li = journals_func.load_ae_obj_li__journal_entry({
|
||||||
api_cfg: $ae_api,
|
api_cfg: $ae_api,
|
||||||
for_obj_type: 'journal',
|
for_obj_type: 'journal',
|
||||||
@@ -174,38 +133,6 @@ $effect(() => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// $effect(() => {
|
|
||||||
// if ($journals_loc.filter__category_code) {
|
|
||||||
// console.log(`Filtering journal entry by category_code: ${$journals_loc.filter__category_code}`);
|
|
||||||
|
|
||||||
// $journals_prom.load__journal_entry_obj_li = journals_func.load_ae_obj_li__journal_entry({
|
|
||||||
// api_cfg: $ae_api,
|
|
||||||
// for_obj_type: 'journal',
|
|
||||||
// for_obj_id: $journals_slct.journal_id,
|
|
||||||
// enabled: $journals_loc.qry__enabled,
|
|
||||||
// hidden: $journals_loc.qry__hidden,
|
|
||||||
// limit: $journals_loc.qry__limit,
|
|
||||||
// order_by_li: $journals_loc.qry__order_by_li,
|
|
||||||
// try_cache: true,
|
|
||||||
// log_lvl: log_lvl,
|
|
||||||
// });
|
|
||||||
// } else {
|
|
||||||
// console.log(`No category_code filter applied.`);
|
|
||||||
// // force_refresh = true;
|
|
||||||
// $journals_prom.load__journal_entry_obj_li = journals_func.load_ae_obj_li__journal_entry({
|
|
||||||
// api_cfg: $ae_api,
|
|
||||||
// for_obj_type: 'journal',
|
|
||||||
// for_obj_id: $journals_slct.journal_id,
|
|
||||||
// enabled: $journals_loc.qry__enabled,
|
|
||||||
// hidden: $journals_loc.qry__hidden,
|
|
||||||
// limit: $journals_loc.qry__limit,
|
|
||||||
// order_by_li: $journals_loc.qry__order_by_li,
|
|
||||||
// try_cache: true,
|
|
||||||
// log_lvl: log_lvl,
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
|
|
||||||
if (browser) {
|
if (browser) {
|
||||||
console.log('Browser environment detected.');
|
console.log('Browser environment detected.');
|
||||||
|
|
||||||
@@ -213,13 +140,6 @@ if (browser) {
|
|||||||
window.parent.postMessage(message, "*");
|
window.parent.postMessage(message, "*");
|
||||||
}
|
}
|
||||||
|
|
||||||
let journal_entry_category_li = [
|
|
||||||
{ code: 'test', name: 'Test' },
|
|
||||||
{ code: 'personal', name: 'Personal' },
|
|
||||||
{ code: 'work', name: 'Work' },
|
|
||||||
{ code: 'other', name: 'Other' },
|
|
||||||
];
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
@@ -247,8 +167,6 @@ let journal_entry_category_li = [
|
|||||||
<!-- <h1>Journals {$lq__journal_obj?.name} - {$lq__journal_entry_obj_li?.length}</h1> -->
|
<!-- <h1>Journals {$lq__journal_obj?.name} - {$lq__journal_entry_obj_li?.length}</h1> -->
|
||||||
|
|
||||||
<div class="flex flex-row items-center justify-between w-full">
|
<div class="flex flex-row items-center justify-between w-full">
|
||||||
{$journals_loc.filter__category_code}
|
|
||||||
|
|
||||||
<a href="/journals" class="novi_btn btn btn-secondary btn-sm
|
<a href="/journals" class="novi_btn btn btn-secondary btn-sm
|
||||||
variant-ghost-tertiary
|
variant-ghost-tertiary
|
||||||
hover:variant-filled-tertiary
|
hover:variant-filled-tertiary
|
||||||
@@ -260,59 +178,74 @@ let journal_entry_category_li = [
|
|||||||
</a>
|
</a>
|
||||||
|
|
||||||
<!-- Add default journal entry -->
|
<!-- Add default journal entry -->
|
||||||
<button
|
<span class="flex flex-row items-center gap-2">
|
||||||
class="novi_btn btn btn-secondary btn-sm
|
<span class="text-sm text-gray-500 hidden md:inline">
|
||||||
variant-ghost-success
|
New Entry:
|
||||||
hover:variant-filled-success
|
</span>
|
||||||
transition"
|
<button
|
||||||
onclick={() => {
|
class="btn btn-sm
|
||||||
// $journals_sess.show__modal_new__journal_entry_obj = true;
|
variant-ghost-success
|
||||||
|
hover:variant-filled-success
|
||||||
|
transition"
|
||||||
|
onclick={() => {
|
||||||
|
// $journals_sess.show__modal_new__journal_entry_obj = true;
|
||||||
|
|
||||||
let data_kv = {
|
let data_kv = {
|
||||||
// journal_id_random: $lq__journal_obj?.journal_id,
|
// journal_id_random: $lq__journal_obj?.journal_id,
|
||||||
category_code: 'test',
|
category_code: 'test',
|
||||||
};
|
};
|
||||||
if ($journals_loc.qry__category_code) {
|
if ($journals_loc.qry__category_code) {
|
||||||
data_kv.category_code = $journals_loc.qry__category_code;
|
data_kv.category_code = $journals_loc.qry__category_code;
|
||||||
}
|
}
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log('Creating new journal entry with data_kv:', data_kv);
|
console.log('Creating new journal entry with data_kv:', data_kv);
|
||||||
}
|
}
|
||||||
journals_func.create_ae_obj__journal_entry({
|
journals_func.create_ae_obj__journal_entry({
|
||||||
api_cfg: $ae_api,
|
api_cfg: $ae_api,
|
||||||
journal_id: $lq__journal_obj?.journal_id,
|
journal_id: $lq__journal_obj?.journal_id,
|
||||||
data_kv: data_kv,
|
data_kv: data_kv,
|
||||||
log_lvl: log_lvl
|
log_lvl: log_lvl
|
||||||
}).then((results) => {
|
}).then((results) => {
|
||||||
console.log('New journal entry created:', results);
|
console.log('New journal entry created:', results);
|
||||||
$journals_slct.journal_entry_id = results?.journal_entry_id_random;
|
$journals_slct.journal_entry_id = results?.journal_entry_id_random;
|
||||||
// alert('Journal entry created successfully!');
|
// alert(`Journal entry created successfully! ${$journals_slct.journal_entry_id}`);
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
console.error('Error updating journal entry:', error);
|
console.error('Error updating journal entry:', error);
|
||||||
alert('Failed to update journal entry.');
|
alert('Failed to update journal entry.');
|
||||||
});
|
}).finally(() => {
|
||||||
}}
|
goto(`/journals/${$lq__journal_obj?.journal_id}/entry/${$journals_slct.journal_entry_id}`);
|
||||||
>
|
});
|
||||||
<span class="fas fa-plus m-1"></span> New Journal Entry
|
}}
|
||||||
</button>
|
>
|
||||||
|
<span class="fas fa-plus m-1"></span> New Journal Entry
|
||||||
|
</button>
|
||||||
|
|
||||||
<!-- Give list of categories to base the new entry on -->
|
<!-- Give list of categories to base the new entry on -->
|
||||||
<select
|
<span class="flex flex-row items-center gap-2">
|
||||||
class="novi_btn btn btn-secondary btn-sm
|
<span class="text-sm text-gray-500 hidden sm:inline">
|
||||||
variant-ghost-primary
|
Category:
|
||||||
hover:variant-filled-primary
|
</span>
|
||||||
transition"
|
<select
|
||||||
bind:value={$journals_loc.qry__category_code}
|
class="novi_btn btn btn-secondary btn-sm
|
||||||
onchange={(event) => {
|
variant-soft-primary
|
||||||
$journals_loc.qry__category_code = event.target.value;
|
hover:variant-filled-primary
|
||||||
console.log('Selected category:', $journals_loc.qry__category_code);
|
transition
|
||||||
}}
|
text-xs
|
||||||
>
|
"
|
||||||
<option value="">Select Category</option>
|
bind:value={$journals_loc.qry__category_code}
|
||||||
{#each journal_entry_category_li as category}
|
onchange={(event) => {
|
||||||
<option value={category.code}>{category.name}</option>
|
$journals_loc.qry__category_code = event.target.value;
|
||||||
{/each}
|
console.log('Selected category:', $journals_loc.qry__category_code);
|
||||||
</select>
|
}}
|
||||||
|
title="Select a category for the new journal entry"
|
||||||
|
>
|
||||||
|
<option value="">Select Category</option>
|
||||||
|
{#each $lq__journal_obj?.cfg_json.category_li as category}
|
||||||
|
<option value={category.code}>{category.name}</option>
|
||||||
|
{/each}
|
||||||
|
</select>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -40,11 +40,20 @@ if (log_lvl) {
|
|||||||
console.log(`ae_acct = `, ae_acct);
|
console.log(`ae_acct = `, ae_acct);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$journals_slct.journal_id = ae_acct.slct.journal_id;
|
||||||
|
let lq__journal_obj = $derived(liveQuery(async () => {
|
||||||
|
let results = await db_journals.journal
|
||||||
|
.where('id')
|
||||||
|
.equals($journals_slct.journal_id)
|
||||||
|
.first();
|
||||||
|
|
||||||
|
return results;
|
||||||
|
}));
|
||||||
|
|
||||||
// For some reason data.params.journal_entry_id (or whatever param) is not being passed to this page when loaded by a link from another page. This seems to be a bug with Svelte or SvelteKit. Hopefully fixed in a future version 5? 2024-11-06
|
// For some reason data.params.journal_entry_id (or whatever param) is not being passed to this page when loaded by a link from another page. This seems to be a bug with Svelte or SvelteKit. Hopefully fixed in a future version 5? 2024-11-06
|
||||||
$journals_slct.journal_entry_id = ae_acct.slct.journal_entry_id;
|
$journals_slct.journal_entry_id = ae_acct.slct.journal_entry_id;
|
||||||
// $journals_slct.journal_entry_obj = ae_acct.slct.journal_entry_obj;
|
// $journals_slct.journal_entry_obj = ae_acct.slct.journal_entry_obj;
|
||||||
|
|
||||||
|
|
||||||
let lq__journal_entry_obj = $derived(liveQuery(async () => {
|
let lq__journal_entry_obj = $derived(liveQuery(async () => {
|
||||||
if (log_lvl) {
|
if (log_lvl) {
|
||||||
console.log(`lq__journal_entry_obj: journal_entry_id = ${$journals_slct?.journal_entry_id}`);
|
console.log(`lq__journal_entry_obj: journal_entry_id = ${$journals_slct?.journal_entry_id}`);
|
||||||
@@ -192,6 +201,7 @@ if (browser) {
|
|||||||
|
|
||||||
{#if $lq__journal_entry_obj}
|
{#if $lq__journal_entry_obj}
|
||||||
<Journal_entry_view
|
<Journal_entry_view
|
||||||
|
lq__journal_obj={lq__journal_obj}
|
||||||
lq__journal_entry_obj={lq__journal_entry_obj}
|
lq__journal_entry_obj={lq__journal_entry_obj}
|
||||||
/>
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
@@ -14,6 +14,9 @@ export async function load({ params, parent }) { // route
|
|||||||
let account_id = data.account_id;
|
let account_id = data.account_id;
|
||||||
let ae_acct = data[account_id];
|
let ae_acct = data[account_id];
|
||||||
|
|
||||||
|
let journal_id = params.journal_id;
|
||||||
|
ae_acct.slct.journal_id = journal_id;
|
||||||
|
|
||||||
let journal_entry_id = params.journal_entry_id;
|
let journal_entry_id = params.journal_entry_id;
|
||||||
if (!journal_entry_id) {
|
if (!journal_entry_id) {
|
||||||
console.log(`ae_journals journals [journal_entry_id] +page.ts: The journal_entry_id was not found in the params!!!`);
|
console.log(`ae_journals journals [journal_entry_id] +page.ts: The journal_entry_id was not found in the params!!!`);
|
||||||
|
|||||||
@@ -1,9 +1,25 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
// *** Import Svelte specific
|
// *** Import Svelte specific
|
||||||
|
import { goto } from '$app/navigation';
|
||||||
|
|
||||||
// import { createIcons, icons } from 'lucide';
|
// import { createIcons, icons } from 'lucide';
|
||||||
// createIcons({ icons });
|
// createIcons({ icons });
|
||||||
|
|
||||||
import { BookHeart, BriefcaseBusiness, Fingerprint, Globe, MessageSquareWarning, Share2, Siren, Skull } from '@lucide/svelte';
|
import {
|
||||||
|
ArrowDown01, ArrowDownUp,
|
||||||
|
BookHeart, BriefcaseBusiness,
|
||||||
|
CalendarClock, CalendarOff,
|
||||||
|
Eye, EyeOff,
|
||||||
|
Flag, FlagOff, Fingerprint,
|
||||||
|
Globe, Group,
|
||||||
|
MessageSquareWarning, Minus,
|
||||||
|
NotebookPen, NotebookText,
|
||||||
|
Pencil,
|
||||||
|
Plus, Search,
|
||||||
|
Shapes, Share2, ShieldCheck, ShieldMinus, Siren, Skull,
|
||||||
|
Tags, Trash2
|
||||||
|
} from '@lucide/svelte';
|
||||||
|
|
||||||
|
|
||||||
// *** Import Aether specific variables and functions
|
// *** Import Aether specific variables and functions
|
||||||
import type { key_val } from '$lib/ae_stores';
|
import type { key_val } from '$lib/ae_stores';
|
||||||
@@ -14,17 +30,22 @@ import { journals_func } from '$lib/ae_journals/ae_journals_functions';
|
|||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
|
lq__journal_obj: any;
|
||||||
lq__journal_entry_obj: any;
|
lq__journal_entry_obj: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
let { log_lvl = 0, lq__journal_entry_obj }: Props = $props();
|
let {
|
||||||
|
log_lvl = 0,
|
||||||
|
lq__journal_obj,
|
||||||
|
lq__journal_entry_obj,
|
||||||
|
}: Props = $props();
|
||||||
|
|
||||||
let ae_promises: key_val = $state({});
|
let ae_promises: key_val = $state({});
|
||||||
// let ae_tmp: key_val = {};
|
// let ae_tmp: key_val = {};
|
||||||
// let ae_trigger: any = null;
|
// let ae_trigger: any = null;
|
||||||
// let ae_triggers: key_val = {};
|
// let ae_triggers: key_val = {};
|
||||||
|
|
||||||
// let tmp_entry_obj = $lq__journal_entry_obj;
|
let tmp_entry_obj_changed: boolean = $state(false);
|
||||||
let tmp_entry_obj: key_val = $state({});
|
let tmp_entry_obj: key_val = $state({});
|
||||||
|
|
||||||
// let tmp_entry_obj = $derived(async () => {
|
// let tmp_entry_obj = $derived(async () => {
|
||||||
@@ -42,22 +63,219 @@ $effect(() => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$effect(() => {
|
||||||
|
if (tmp_entry_obj) {
|
||||||
|
tmp_entry_obj_changed = JSON.stringify(tmp_entry_obj) != JSON.stringify($lq__journal_entry_obj);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// const test_html = marked.parse('# Marked in Node.js\n\nRendered by **marked**.');
|
||||||
|
|
||||||
// Reminder: Styling is being done with Tailwind CSS, not Bootstrap.
|
// Reminder: Styling is being done with Tailwind CSS, not Bootstrap.
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
<section class="svelte_component ae_section ae_view journal_entry_obj view__journal_entry_obj bg-white rounded-lg w-full p-2 m-2" bind:clientHeight={$ae_loc.iframe_height_modal_body}>
|
<section class="svelte_component ae_section ae_view journal_entry_obj view__journal_entry_obj bg-white flex flex-col items-center justify-center rounded-lg w-full p-2 m-2 space-y-2" bind:clientHeight={$ae_loc.iframe_height_modal_body}>
|
||||||
|
|
||||||
{#if $lq__journal_entry_obj}
|
{#if $lq__journal_entry_obj}
|
||||||
<header class="ae_header journal_entry__header flex flex-col items-center justify-center">
|
<header class="ae_header journal_entry__header flex flex-row gap-2 items-center justify-between w-full">
|
||||||
<h2 class="journal_entry__name h3">
|
<span class="flex flex-row gap-2 items-center justify-start">
|
||||||
{@html $lq__journal_entry_obj?.name ?? 'Loading...'}
|
<!-- Toggle edit for journal entry -->
|
||||||
{#await $journals_prom.load__journal_entry_obj_li}
|
<button
|
||||||
<span class="fas fa-spinner fa-spin"></span>
|
type="button"
|
||||||
{:then}
|
onclick={() => {
|
||||||
<!-- done -->
|
// Ask if they would like to save changes before toggling edit mode off.
|
||||||
{/await}
|
if ($journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id]) {
|
||||||
</h2>
|
if (tmp_entry_obj_changed && confirm('Would you like to save changes to this journal entry before exiting edit mode?')) {
|
||||||
|
// Call API to save the content
|
||||||
|
let data_kv = {
|
||||||
|
name: tmp_entry_obj?.name,
|
||||||
|
category_code: tmp_entry_obj?.category_code,
|
||||||
|
content: tmp_entry_obj?.content
|
||||||
|
};
|
||||||
|
journals_func.update_ae_obj__journal_entry({
|
||||||
|
api_cfg: $ae_api,
|
||||||
|
journal_entry_id: $lq__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.');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Toggle edit mode
|
||||||
|
if ($journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id]) {
|
||||||
|
$journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id] = false;
|
||||||
|
} else {
|
||||||
|
$journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id] = true;
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
class="btn btn-icon-sm inline-block"
|
||||||
|
title="Toggle edit mode for this journal entry"
|
||||||
|
>
|
||||||
|
{#if $journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id]}
|
||||||
|
<Pencil strokeWidth="2.5" color="blue" />
|
||||||
|
{:else}
|
||||||
|
<Pencil strokeWidth="1" color="gray" />
|
||||||
|
{/if}
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<h2 class="journal_entry__name h3">
|
||||||
|
|
||||||
|
<!-- <span class="fas fa-spinner fa-spin"></span> -->
|
||||||
|
<span class="journal_entry__name inline-block">
|
||||||
|
<!-- Allow for toggle between view and edit of journal entry. -->
|
||||||
|
{#if $journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id]}
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
bind:value={tmp_entry_obj.name}
|
||||||
|
class="input input-bordered"
|
||||||
|
placeholder="Journal Entry Name"
|
||||||
|
title="Edit the name of this journal entry"
|
||||||
|
/>
|
||||||
|
{:else}
|
||||||
|
{#if ($lq__journal_entry_obj?.name)}
|
||||||
|
<NotebookText class="m-1 inline-block"/>
|
||||||
|
{@html $lq__journal_entry_obj?.name}
|
||||||
|
{:else}
|
||||||
|
<CalendarClock class="m-1 inline-block"/>
|
||||||
|
{ae_util.iso_datetime_formatter($lq__journal_entry_obj?.created_on, 'datetime_iso_12_no_seconds')}
|
||||||
|
{/if}
|
||||||
|
{/if}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
</h2>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="flex flex-row gap-2 items-center justify-end">
|
||||||
|
|
||||||
|
<!-- Tags for journal entry. Comma delimited list. -->
|
||||||
|
{#if $journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id]}
|
||||||
|
<div class="tags flex flex-row gap-1 items-center justify-start border border-gray-200 rounded-lg p-1">
|
||||||
|
<span class="text-sm text-gray-500">
|
||||||
|
<Tags class="m-1 inline-block" />
|
||||||
|
<!-- <span class="hidden sm:inline">Tags:</span> -->
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
bind:value={tmp_entry_obj.tags}
|
||||||
|
class="input input-bordered inline-block text-sm"
|
||||||
|
placeholder="Tags (comma delimited)"
|
||||||
|
title="Edit the tags for this journal entry"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{:else}
|
||||||
|
{#if $lq__journal_entry_obj.tags && $lq__journal_entry_obj.tags.length}
|
||||||
|
<div class="tags flex flex-wrap gap-1 items-center justify-start border border-gray-200 rounded-lg p-1">
|
||||||
|
<span class="text-sm text-gray-500">
|
||||||
|
<Tags class="m-1 inline-block" />
|
||||||
|
<span class="hidden md:inline">Tags</span>
|
||||||
|
</span>
|
||||||
|
<!-- <Tags class="m-1 inline-block" />
|
||||||
|
<span class="text-sm text-gray-500 hidden md:inline">Tags</span> -->
|
||||||
|
|
||||||
|
{#each $lq__journal_entry_obj.tags.split(',') as tag}
|
||||||
|
<span
|
||||||
|
class="btn btn-sm variant-outline-tertiary hover:variant-ghost-tertiary transition py-1 px-2"
|
||||||
|
title={`Tag: ${tag.trim()}`}
|
||||||
|
>
|
||||||
|
{tag.trim()}
|
||||||
|
</span>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<!-- Category code for journal entry -->
|
||||||
|
{#if $journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id]}
|
||||||
|
<!-- <input
|
||||||
|
type="text"
|
||||||
|
bind:value={tmp_entry_obj.category_code}
|
||||||
|
class="input input-bordered"
|
||||||
|
placeholder="Category Code"
|
||||||
|
title="Edit the category code for this journal entry"
|
||||||
|
/> -->
|
||||||
|
|
||||||
|
<!-- Give list of categories to base the new entry on -->
|
||||||
|
<span class="flex flex-row items-center gap-2">
|
||||||
|
<span class="text-sm text-gray-500 hidden sm:inline">
|
||||||
|
Category:
|
||||||
|
</span>
|
||||||
|
<select
|
||||||
|
class="novi_btn btn btn-secondary btn-sm
|
||||||
|
variant-soft-primary
|
||||||
|
hover:variant-filled-primary
|
||||||
|
transition
|
||||||
|
text-xs
|
||||||
|
"
|
||||||
|
bind:value={tmp_entry_obj.category_code}
|
||||||
|
onchange={(event) => {
|
||||||
|
tmp_entry_obj.category_code = event.target.value;
|
||||||
|
console.log('Selected category:', tmp_entry_obj.category_code);
|
||||||
|
|
||||||
|
// Call API to save the content
|
||||||
|
let data_kv = {
|
||||||
|
category_code: tmp_entry_obj?.category_code
|
||||||
|
};
|
||||||
|
journals_func.update_ae_obj__journal_entry({
|
||||||
|
api_cfg: $ae_api,
|
||||||
|
journal_entry_id: $lq__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.');
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
title="Select a category for the new journal entry"
|
||||||
|
>
|
||||||
|
<option value="">Select Category</option>
|
||||||
|
{#each $lq__journal_obj?.cfg_json.category_li as category}
|
||||||
|
<option value={category.code}
|
||||||
|
selected={$lq__journal_entry_obj.category_code == category.code}
|
||||||
|
title={`Category: ${category.name}`}
|
||||||
|
>
|
||||||
|
{category.name}
|
||||||
|
</option>
|
||||||
|
{/each}
|
||||||
|
</select>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
{:else}
|
||||||
|
|
||||||
|
{#if $lq__journal_entry_obj.category_code}
|
||||||
|
<!-- When clicked, this will change to edit the journal entry. -->
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onclick={() => {
|
||||||
|
// Toggle edit mode
|
||||||
|
$journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id] = true;
|
||||||
|
// tmp_entry_obj.category_code = $lq__journal_entry_obj.category_code;
|
||||||
|
console.log('Editing category:', tmp_entry_obj.category_code);
|
||||||
|
}}
|
||||||
|
class="btn btn-sm variant-ghost-secondary hover:variant-filled-secondary transition py-1 px-2"
|
||||||
|
title={`Filter by category: ${$lq__journal_entry_obj.category_code}`}
|
||||||
|
>
|
||||||
|
<Shapes class="m-1 inline-block"/>
|
||||||
|
{$lq__journal_entry_obj.category_code ?? '-- no category --'}
|
||||||
|
</button>
|
||||||
|
{/if}
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</header>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="flex flex-row gap-2 items-center justify-evenly w-full max-w-sm"
|
class="flex flex-row gap-2 items-center justify-evenly w-full max-w-sm"
|
||||||
@@ -285,9 +503,8 @@ $effect(() => {
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<pre
|
<div
|
||||||
ondblclick={() => {
|
ondblclick={() => {
|
||||||
if ($ae_loc.trusted_access) {
|
if ($ae_loc.trusted_access) {
|
||||||
// Toggle edit mode
|
// Toggle edit mode
|
||||||
@@ -295,12 +512,21 @@ $effect(() => {
|
|||||||
$journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id] = $journals_loc.entry.edit;
|
$journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id] = $journals_loc.entry.edit;
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
role="button"
|
||||||
|
tabindex="0"
|
||||||
class:hidden={!$ae_loc.trusted_access || $journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id]}
|
class:hidden={!$ae_loc.trusted_access || $journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id]}
|
||||||
|
class="w-full font-mono shadow-md rounded-lg border-gray-500 bg-gray-100 p-2"
|
||||||
>
|
>
|
||||||
{$lq__journal_entry_obj?.content}
|
<article class="prose">
|
||||||
</pre>
|
{@html $lq__journal_entry_obj?.content_md_html}
|
||||||
|
<!-- {@html marked.parse($lq__journal_entry_obj?.content)} -->
|
||||||
|
</article>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="flex flex-col items-center justify-center w-full max-w-6xl">
|
<div
|
||||||
|
class="flex flex-col items-center justify-center w-full max-w-6xl"
|
||||||
|
class:hidden={!$journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id] && $lq__journal_entry_obj?.content?.length}
|
||||||
|
>
|
||||||
|
|
||||||
<textarea
|
<textarea
|
||||||
bind:value={tmp_entry_obj.content}
|
bind:value={tmp_entry_obj.content}
|
||||||
@@ -311,11 +537,12 @@ $effect(() => {
|
|||||||
$journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id] = $journals_loc.entry.edit;
|
$journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id] = $journals_loc.entry.edit;
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
class:hidden={!$ae_loc.trusted_access || !$journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id]}
|
|
||||||
class="w-full min-h-10 h-96 p-2 border border-gray-300 rounded-lg"
|
class="w-full min-h-10 h-96 p-2 border border-gray-300 rounded-lg"
|
||||||
placeholder="Edit journal entry content here..."
|
placeholder="Edit journal entry content here..."
|
||||||
></textarea>
|
></textarea>
|
||||||
|
|
||||||
|
<!-- Only enable editing if the user has trusted access -->
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onclick={() => {
|
onclick={() => {
|
||||||
@@ -323,6 +550,8 @@ $effect(() => {
|
|||||||
if ($ae_loc.trusted_access) {
|
if ($ae_loc.trusted_access) {
|
||||||
// Call API to save the content
|
// Call API to save the content
|
||||||
let data_kv = {
|
let data_kv = {
|
||||||
|
name: tmp_entry_obj?.name,
|
||||||
|
category_code: tmp_entry_obj?.category_code,
|
||||||
content: tmp_entry_obj?.content
|
content: tmp_entry_obj?.content
|
||||||
};
|
};
|
||||||
journals_func.update_ae_obj__journal_entry({
|
journals_func.update_ae_obj__journal_entry({
|
||||||
@@ -332,30 +561,254 @@ $effect(() => {
|
|||||||
log_lvl: log_lvl
|
log_lvl: log_lvl
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
// Optionally, you can provide feedback to the user
|
// Optionally, you can provide feedback to the user
|
||||||
alert('Journal entry updated successfully!');
|
// alert('Journal entry updated successfully!');
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
console.error('Error updating journal entry:', error);
|
console.error('Error updating journal entry:', error);
|
||||||
alert('Failed to update journal entry.');
|
alert('Failed to update journal entry.');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
disabled={!tmp_entry_obj_changed}
|
||||||
|
class:variant-filled-error={tmp_entry_obj_changed}
|
||||||
class="
|
class="
|
||||||
btn btn-sm md:btn-md lg:btn-lg
|
btn btn-sm md:btn-md lg:btn-lg
|
||||||
variant-soft-primary hover:variant-filled-primary
|
|
||||||
min-w-72 w-full lg:min-w-96
|
min-w-72 w-full lg:min-w-96
|
||||||
max-w-96
|
max-w-96
|
||||||
|
hover:variant-outline-success
|
||||||
|
hover:variant-filled-success
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
Save Changes
|
Save Changes?
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- <div>
|
||||||
|
{@html test_html}
|
||||||
|
</div> -->
|
||||||
|
|
||||||
|
<div class="ae_meta flex flex-row flex-wrap gap-2 items-center justify-between w-full">
|
||||||
|
<!-- {$lq__journal_entry_obj?.priority}
|
||||||
|
{$lq__journal_entry_obj?.sort}
|
||||||
|
{$lq__journal_entry_obj?.group}
|
||||||
|
{$lq__journal_entry_obj?.hide}
|
||||||
|
{$lq__journal_entry_obj?.enable} -->
|
||||||
|
|
||||||
|
<!-- Set/unset priority (boolean) -->
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onclick={() => {
|
||||||
|
if ($ae_loc.trusted_access) {
|
||||||
|
let data_kv = {
|
||||||
|
priority: $lq__journal_entry_obj?.priority ? false : true
|
||||||
|
};
|
||||||
|
journals_func.update_ae_obj__journal_entry({
|
||||||
|
api_cfg: $ae_api,
|
||||||
|
journal_entry_id: $lq__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="btn-icon-sm variant-soft-tertiary transition"
|
||||||
|
title="Toggle priority of this journal entry"
|
||||||
|
>
|
||||||
|
{#if $lq__journal_entry_obj?.priority}
|
||||||
|
<Flag strokeWidth="2.5" color="green" />
|
||||||
|
{:else}
|
||||||
|
<FlagOff strokeWidth="1" color="gray" />
|
||||||
|
{/if}
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<!-- Set sort order (number) -->
|
||||||
|
<span class="flex flex-row items-center justify-center">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onclick={() => {
|
||||||
|
let data_kv = {
|
||||||
|
sort: $lq__journal_entry_obj?.sort ? $lq__journal_entry_obj?.sort + 1 : 1
|
||||||
|
};
|
||||||
|
journals_func.update_ae_obj__journal_entry({
|
||||||
|
api_cfg: $ae_api,
|
||||||
|
journal_entry_id: $lq__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="btn-icon-sm variant-soft-tertiary transition"
|
||||||
|
title="Increment sort order of this journal entry"
|
||||||
|
>
|
||||||
|
<Plus strokeWidth="2.5" color="blue" />
|
||||||
|
</button>
|
||||||
|
<span class="m-1">
|
||||||
|
{$lq__journal_entry_obj?.sort}
|
||||||
|
</span>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onclick={() => {
|
||||||
|
let data_kv = {
|
||||||
|
sort: $lq__journal_entry_obj?.sort ? $lq__journal_entry_obj?.sort - 1 : 0
|
||||||
|
};
|
||||||
|
journals_func.update_ae_obj__journal_entry({
|
||||||
|
api_cfg: $ae_api,
|
||||||
|
journal_entry_id: $lq__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="btn-icon-sm variant-soft-tertiary transition"
|
||||||
|
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={() => {
|
||||||
|
let data_kv = {
|
||||||
|
group: tmp_entry_obj.group
|
||||||
|
};
|
||||||
|
journals_func.update_ae_obj__journal_entry({
|
||||||
|
api_cfg: $ae_api,
|
||||||
|
journal_entry_id: $lq__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="input input-sm input-bordered w-24"
|
||||||
|
title="Set group of this journal entry"
|
||||||
|
/>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Set/unset hide (boolean) -->
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onclick={() => {
|
||||||
|
let data_kv = {
|
||||||
|
hide: $lq__journal_entry_obj?.hide ? false : true
|
||||||
|
};
|
||||||
|
journals_func.update_ae_obj__journal_entry({
|
||||||
|
api_cfg: $ae_api,
|
||||||
|
journal_entry_id: $lq__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="btn btn-sm md:btn-md 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={() => {
|
||||||
|
let data_kv = {
|
||||||
|
enable: $lq__journal_entry_obj?.enable ? false : true
|
||||||
|
};
|
||||||
|
journals_func.update_ae_obj__journal_entry({
|
||||||
|
api_cfg: $ae_api,
|
||||||
|
journal_entry_id: $lq__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="btn btn-sm md:btn-md 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?`)) {
|
||||||
|
journals_func.delete_ae_obj_id__journal_entry({
|
||||||
|
api_cfg: $ae_api,
|
||||||
|
journal_entry_id: $lq__journal_entry_obj?.journal_entry_id,
|
||||||
|
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="btn btn-sm md:btn-md variant-soft-error hover:variant-filled-error transition"
|
||||||
|
title="Delete this journal entry"
|
||||||
|
>
|
||||||
|
<Trash2 strokeWidth="2.5" color="red" class="inline-block" />
|
||||||
|
<span class="hidden md:inline">Delete</span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
|
||||||
<div>
|
|
||||||
{$lq__journal_entry_obj?.keywords}
|
|
||||||
{#if $ae_loc.trusted_access && $ae_loc.edit_mode}
|
{#if $ae_loc.trusted_access && $ae_loc.edit_mode}
|
||||||
({$lq__journal_entry_obj?.created_on} {$lq__journal_entry_obj?.updated_on ?? ''})
|
<span class="flex flex-row items-center justify-center text-sm text-gray-500">
|
||||||
|
{ae_util.iso_datetime_formatter($lq__journal_entry_obj?.created_on, 'datetime_iso_12_no_seconds')}
|
||||||
|
{$lq__journal_entry_obj?.updated_on ?
|
||||||
|
` | Last updated: ${ae_util.iso_datetime_formatter($lq__journal_entry_obj?.updated_on, 'datetime_iso_12_no_seconds')}` : ''}
|
||||||
|
</span>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ let log_lvl: number = 1;
|
|||||||
// *** Import Svelte specific
|
// *** Import Svelte specific
|
||||||
import { goto, invalidate, pushState, replaceState } from '$app/navigation';
|
import { goto, invalidate, pushState, replaceState } from '$app/navigation';
|
||||||
|
|
||||||
import { NotebookText, Shapes } from '@lucide/svelte';
|
import { CalendarClock, NotebookPen, NotebookText, Shapes, Tags } from '@lucide/svelte';
|
||||||
|
|
||||||
|
|
||||||
// *** Import Aether specific variables and functions
|
// *** Import Aether specific variables and functions
|
||||||
@@ -46,55 +46,84 @@ let ae_promises: key_val = $state({});
|
|||||||
>
|
>
|
||||||
|
|
||||||
<header class="ae_header flex flex-row gap-2 items-center justify-between w-full">
|
<header class="ae_header flex flex-row gap-2 items-center justify-between w-full">
|
||||||
<a
|
|
||||||
href="/journals/{journals_journal_entry_obj?.journal_id}/entry/{journals_journal_entry_obj?.journal_entry_id}"
|
|
||||||
class="btn btn-secondary variant-ghost-primary hover:variant-filled-primary transition"
|
|
||||||
title={`View: ${journals_journal_entry_obj?.name}`}
|
|
||||||
>
|
|
||||||
<NotebookText class="m-1"/>
|
|
||||||
<span class="hidden md:inline">
|
|
||||||
View
|
|
||||||
</span>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
{#if journals_journal_entry_obj.category_code}
|
|
||||||
<!-- When clicked, this will filter by the category code. -->
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
onclick={() => {
|
|
||||||
if (log_lvl) {
|
|
||||||
console.log('$journals_loc.filter__category_code', $journals_loc.filter__category_code);
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
// $journals_loc = {
|
|
||||||
// ...$journals_loc,
|
|
||||||
// };
|
|
||||||
$journals_trig.journal_entry_li = true;
|
|
||||||
if (log_lvl) {
|
|
||||||
console.log('$journals_loc.filter__category_code', $journals_loc.filter__category_code);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
class="btn variant-ghost-secondary hover:variant-filled-secondary transition"
|
|
||||||
title={`Filter by category: ${journals_journal_entry_obj.category_code}`}
|
|
||||||
>
|
|
||||||
<Shapes class="m-1 inline-block"/>
|
|
||||||
{journals_journal_entry_obj.category_code ?? '-- no category --'}
|
|
||||||
</button>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
<h3 class="journal__name h4">
|
<h3 class="journal__name h4">
|
||||||
<span class="journal__name">{@html journals_journal_entry_obj.name ?? ae_util.iso_datetime_formatter(journals_journal_entry_obj.created_on, 'datetime_iso_12_no_seconds')}</span>
|
<span class="journal_entry__name">
|
||||||
|
{#if (journals_journal_entry_obj.name)}
|
||||||
|
<NotebookText class="m-1 inline-block"/>
|
||||||
|
{@html journals_journal_entry_obj.name}
|
||||||
|
{:else}
|
||||||
|
<CalendarClock class="m-1 inline-block"/>
|
||||||
|
{ae_util.iso_datetime_formatter(journals_journal_entry_obj.created_on, 'datetime_iso_12_no_seconds')}
|
||||||
|
{/if}
|
||||||
|
</span>
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
|
<div class="flex flex-row 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="m-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-outline-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={() => {
|
||||||
|
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="btn btn-sm variant-ghost-secondary hover:variant-filled-secondary transition py-1 px-2"
|
||||||
|
title={`Filter by category: ${journals_journal_entry_obj.category_code}`}
|
||||||
|
>
|
||||||
|
<Shapes class="m-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 btn-secondary 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="m-1 inline-block"/>
|
||||||
|
<span class="hidden md:inline">
|
||||||
|
View
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{#if journals_journal_entry_obj.content}<pre class="journal__content p-2 bg-white shadow-md rounded-lg text-wrap text-sm font-normal whitespace-pre-wrap">{@html journals_journal_entry_obj.content}</pre>{/if}
|
{#if journals_journal_entry_obj.content}
|
||||||
|
<div class="journal__content w-full p-2 bg-white shadow-md rounded-lg text-wrap text-sm font-mono whitespace-pre-wrap">
|
||||||
|
{@html journals_journal_entry_obj.content}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
<!-- <div class="ae_options flex flex-row flex-wrap gap-2 items-center justify-center"> -->
|
<!-- <div class="ae_options flex flex-row flex-wrap gap-2 items-center justify-center"> -->
|
||||||
|
|
||||||
@@ -166,26 +195,28 @@ let ae_promises: key_val = $state({});
|
|||||||
|
|
||||||
|
|
||||||
<section
|
<section
|
||||||
class="ae_meta mt-2 flex flex-col sm:flex-row gap-1 items-center justify-center text-sm text-gray-500"
|
class="ae_meta mt-2 flex flex-col sm:flex-row gap-2 items-center justify-center text-xs text-gray-500"
|
||||||
class:hidden={!$ae_loc.administrator_access}
|
class:hidden={!$ae_loc.administrator_access}
|
||||||
>
|
>
|
||||||
<span
|
<!-- <span
|
||||||
class="journal_entry__journal_entry_type"
|
class="journal_entry__journal_entry_type"
|
||||||
class:hidden={!journals_journal_entry_obj.journal_entry_type}
|
class:hidden={!journals_journal_entry_obj.journal_entry_type}
|
||||||
>
|
>
|
||||||
Type: {journals_journal_entry_obj.journal_entry_type}
|
Type: {journals_journal_entry_obj.journal_entry_type}
|
||||||
</span>
|
</span> -->
|
||||||
<span class="ae_group">
|
<span class="flex flex-row gap-1 items-center justify-center">
|
||||||
<span
|
<span
|
||||||
class="journal_entry__created_on"
|
class="journal_entry__created_on"
|
||||||
>
|
>
|
||||||
Created on: {ae_util.iso_datetime_formatter(journals_journal_entry_obj.created_on, 'datetime_12_long')}
|
Created:
|
||||||
|
{ae_util.iso_datetime_formatter(journals_journal_entry_obj.created_on, 'datetime_12_long')}
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
class="journal_entry__updated_on"
|
class="journal_entry__updated_on"
|
||||||
class:hidden={!journals_journal_entry_obj.updated_on}
|
class:hidden={!journals_journal_entry_obj.updated_on}
|
||||||
>
|
>
|
||||||
Updated on: {ae_util.iso_datetime_formatter(journals_journal_entry_obj.updated_on, 'datetime_12_long')}
|
Last update:
|
||||||
|
{ae_util.iso_datetime_formatter(journals_journal_entry_obj.updated_on, 'datetime_12_long')}
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
Reference in New Issue
Block a user