style(journals): stabilize and standardize all configuration interfaces
- Implemented 'untrack' safeguards in all modal effect blocks to prevent reactivity loops. - Standardized Module, Journal, and Entry configuration with unified tabbed UI and Aether Orange theme. - Fixed critical 'journal is undefined' and ReferenceErrors in configuration modals. - Restored missing button toggles and visibility options in journal-level settings. - Documented Dexie liveQuery '$' prefix mandate in GEMINI.md and project documentation. - Eliminated legacy JournalEntry_SettingsMenu in favor of ModalJournalEntryConfig.
This commit is contained in:
@@ -2,17 +2,14 @@
|
||||
/**
|
||||
* ae_comp__journal_obj_id_edit.svelte
|
||||
* Standardized Journal-level configuration.
|
||||
* Restored missing visibility and button toggles.
|
||||
*/
|
||||
import {
|
||||
CalendarClock,
|
||||
Check,
|
||||
Settings,
|
||||
X,
|
||||
Database,
|
||||
CodeXml,
|
||||
ShieldCheck,
|
||||
BookOpenText,
|
||||
MousePointerClick,
|
||||
Trash2,
|
||||
Fingerprint,
|
||||
LockKeyhole,
|
||||
@@ -20,13 +17,28 @@
|
||||
Minus,
|
||||
Palette,
|
||||
MonitorPlay,
|
||||
Layout
|
||||
Layout,
|
||||
Eye,
|
||||
EyeOff,
|
||||
Siren,
|
||||
MessageSquareWarning,
|
||||
Copy,
|
||||
FilePlus,
|
||||
Globe,
|
||||
BookHeart,
|
||||
BriefcaseBusiness,
|
||||
Target,
|
||||
Expand,
|
||||
BetweenVerticalEnd,
|
||||
BetweenVerticalStart,
|
||||
X,
|
||||
Settings
|
||||
} from '@lucide/svelte';
|
||||
import { Modal } from 'flowbite-svelte';
|
||||
import { goto } from '$app/navigation';
|
||||
import { untrack } from 'svelte';
|
||||
|
||||
// *** Import Aether specific variables and functions
|
||||
import type { key_val } from '$lib/stores/ae_stores';
|
||||
import {
|
||||
ae_loc,
|
||||
ae_api
|
||||
@@ -57,8 +69,15 @@
|
||||
|
||||
// Deep copy on mount or when lq changes to ensure we have a working copy
|
||||
$effect(() => {
|
||||
if (show && lq__journal_obj && !tmp__journal_obj.journal_id) {
|
||||
tmp__journal_obj = JSON.parse(JSON.stringify(lq__journal_obj));
|
||||
if (show && lq__journal_obj) {
|
||||
const source_id = lq__journal_obj.journal_id;
|
||||
untrack(() => {
|
||||
if (!tmp__journal_obj.journal_id || tmp__journal_obj.journal_id !== source_id) {
|
||||
tmp__journal_obj = JSON.parse(JSON.stringify(lq__journal_obj));
|
||||
// Ensure cfg_json exists
|
||||
if (!tmp__journal_obj.cfg_json) tmp__journal_obj.cfg_json = {};
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -69,26 +88,10 @@
|
||||
}
|
||||
|
||||
try {
|
||||
const data_kv = {
|
||||
name: tmp__journal_obj.name,
|
||||
description: tmp__journal_obj.description ?? '',
|
||||
type_code: tmp__journal_obj.type_code,
|
||||
passcode: tmp__journal_obj.passcode,
|
||||
private_passcode: tmp__journal_obj.private_passcode,
|
||||
passcode_timeout: tmp__journal_obj.passcode_timeout,
|
||||
auth_key: tmp__journal_obj.auth_key,
|
||||
cfg_json: tmp__journal_obj.cfg_json,
|
||||
group: tmp__journal_obj.group,
|
||||
sort: tmp__journal_obj.sort,
|
||||
hide: tmp__journal_obj.hide,
|
||||
enable: tmp__journal_obj.enable,
|
||||
priority: tmp__journal_obj.priority
|
||||
};
|
||||
|
||||
await journals_func.update_ae_obj__journal({
|
||||
api_cfg: $ae_api,
|
||||
journal_id: lq__journal_obj?.journal_id,
|
||||
data_kv: data_kv,
|
||||
data_kv: tmp__journal_obj,
|
||||
log_lvl: log_lvl
|
||||
});
|
||||
show = false;
|
||||
@@ -128,11 +131,11 @@
|
||||
{#snippet header()}
|
||||
<h3 class="flex items-center gap-2 text-lg font-bold">
|
||||
<BookOpenText class="text-primary-500" />
|
||||
<span>Edit Journal: {lq__journal_obj?.name ?? '--'}</span>
|
||||
<span>Edit Journal: {$lq__journal_obj?.name ?? '--'}</span>
|
||||
</h3>
|
||||
{/snippet}
|
||||
|
||||
<div class="space-y-6 py-2 h-[70vh] overflow-y-auto px-4">
|
||||
<div class="space-y-6 py-2 h-[75vh] overflow-y-auto px-4">
|
||||
<!-- Navigation Tabs -->
|
||||
<div class="flex justify-center gap-1 mb-4 p-1 bg-surface-500/10 rounded-lg max-w-fit mx-auto sticky top-0 z-10 backdrop-blur-sm">
|
||||
<button class="btn btn-sm transition-all {tab === 'general' ? 'variant-filled-primary' : 'variant-soft-surface'}" onclick={() => (tab = 'general')}>
|
||||
@@ -180,10 +183,10 @@
|
||||
<!-- Categories -->
|
||||
<section class="space-y-4 p-2">
|
||||
<h2 class="text-lg font-bold flex items-center gap-2 border-b border-surface-500/30 pb-2">
|
||||
<Settings size="1em" class="text-primary-500" />
|
||||
<MonitorPlay size="1em" class="text-primary-500" />
|
||||
Journal Categories
|
||||
</h2>
|
||||
<div class="space-y-2 bg-surface-500/5 p-4 rounded-lg">
|
||||
<div class="space-y-2 bg-surface-500/5 p-4 rounded-lg border border-surface-500/10">
|
||||
{#each tmp__journal_obj?.cfg_json?.category_li ?? [] as category, i}
|
||||
<div class="flex gap-2 items-center">
|
||||
<input type="text" bind:value={category.code} class="input input-sm w-32" placeholder="Code" />
|
||||
@@ -210,7 +213,7 @@
|
||||
<LockKeyhole size="1.2em" class="text-primary-500" />
|
||||
Encryption Passcodes
|
||||
</h2>
|
||||
<div class="bg-warning-500/10 border border-warning-500/30 p-4 rounded-lg space-y-4">
|
||||
<div class="bg-warning-500/10 border border-warning-500/30 p-4 rounded-lg space-y-4 shadow-inner">
|
||||
<label class="label">
|
||||
<span class="text-xs font-bold uppercase tracking-wider opacity-70">Primary Passcode (Stored)</span>
|
||||
<div class="flex gap-2">
|
||||
@@ -236,25 +239,27 @@
|
||||
<Fingerprint size="1.2em" class="text-primary-500" />
|
||||
Status & Lifecycle
|
||||
</h2>
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<label class="flex items-center space-x-3 cursor-pointer p-3 rounded-lg bg-surface-500/5 border border-surface-500/10">
|
||||
<input type="checkbox" bind:checked={tmp__journal_obj.enable} class="checkbox" />
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<label class="flex items-center space-x-3 cursor-pointer p-3 rounded-lg bg-surface-500/5 border border-surface-500/10 transition-colors hover:bg-surface-500/10">
|
||||
<input type="checkbox" bind:checked={tmp__journal_obj.enable} class="checkbox checkbox-primary" />
|
||||
<span class="font-bold">Enabled</span>
|
||||
</label>
|
||||
<label class="flex items-center space-x-3 cursor-pointer p-3 rounded-lg bg-surface-500/5 border border-surface-500/10">
|
||||
<input type="checkbox" bind:checked={tmp__journal_obj.hide} class="checkbox" />
|
||||
<label class="flex items-center space-x-3 cursor-pointer p-3 rounded-lg bg-surface-500/5 border border-surface-500/10 transition-colors hover:bg-surface-500/10">
|
||||
<input type="checkbox" bind:checked={tmp__journal_obj.hide} class="checkbox checkbox-primary" />
|
||||
<span class="font-bold">Hidden</span>
|
||||
</label>
|
||||
<label class="flex items-center space-x-3 cursor-pointer p-3 rounded-lg bg-surface-500/5 border border-surface-500/10">
|
||||
<input type="checkbox" bind:checked={tmp__journal_obj.priority} class="checkbox" />
|
||||
<label class="flex items-center space-x-3 cursor-pointer p-3 rounded-lg bg-surface-500/5 border border-surface-500/10 transition-colors hover:bg-surface-500/10">
|
||||
<input type="checkbox" bind:checked={tmp__journal_obj.priority} class="checkbox checkbox-primary" />
|
||||
<span class="font-bold">Priority Journal</span>
|
||||
</label>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<button class="btn btn-sm variant-filled-error w-full mt-12" onclick={delete_journal}>
|
||||
<Trash2 size="1.1em" class="mr-2" /> Delete Entire Journal
|
||||
</button>
|
||||
<section class="pt-8">
|
||||
<button class="btn btn-sm variant-filled-error w-full shadow-lg" onclick={delete_journal}>
|
||||
<Trash2 size="1.1em" class="mr-2" /> Delete Entire Journal
|
||||
</button>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
{:else if tab === 'ui'}
|
||||
@@ -262,9 +267,9 @@
|
||||
<section class="space-y-4 p-2">
|
||||
<h2 class="text-lg font-bold flex items-center gap-2 border-b border-surface-500/30 pb-2">
|
||||
<MonitorPlay size="1.2em" class="text-primary-500" />
|
||||
Editor & Viewer
|
||||
Default View Modes
|
||||
</h2>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 bg-surface-500/5 p-4 rounded-lg border border-surface-500/10">
|
||||
<label class="label">
|
||||
<span class="text-sm font-bold opacity-70">Preferred Viewer</span>
|
||||
<select bind:value={tmp__journal_obj.cfg_json.pref_viewer} class="select variant-form-material">
|
||||
@@ -280,25 +285,126 @@
|
||||
<option value="codemirror">CodeMirror (Advanced)</option>
|
||||
</select>
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="text-sm font-bold opacity-70">Color Scheme</span>
|
||||
<select bind:value={tmp__journal_obj.cfg_json.color_scheme} class="select variant-form-material">
|
||||
<option value="">Default (Slate)</option>
|
||||
<option value="blue">Deep Blue</option>
|
||||
<option value="green">Nature Green</option>
|
||||
<option value="orange">Aether Orange</option>
|
||||
<option value="red">Warning Red</option>
|
||||
<option value="yellow">Caution Yellow</option>
|
||||
</select>
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="text-sm font-bold opacity-70">Quick Add Placement</span>
|
||||
<select bind:value={tmp__journal_obj.cfg_json.entry_add_text} class="select variant-form-material">
|
||||
<option value="append">Append to End (Default)</option>
|
||||
<option value="prepend">Prepend to Start</option>
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Visibility Toggles (Restored) -->
|
||||
<section class="space-y-4 p-2">
|
||||
<h2 class="text-lg font-bold flex items-center gap-2 border-b border-surface-500/30 pb-2">
|
||||
<Eye size="1.2em" class="text-primary-500" />
|
||||
Entry Visibility (Global)
|
||||
</h2>
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-2">
|
||||
<label class="flex items-center space-x-2 cursor-pointer p-2 bg-surface-500/5 rounded border border-surface-500/10">
|
||||
<input type="checkbox" bind:checked={tmp__journal_obj.cfg_json.hide_private} class="checkbox checkbox-sm" />
|
||||
<span class="text-xs font-bold">Hide Private</span>
|
||||
</label>
|
||||
<label class="flex items-center space-x-2 cursor-pointer p-2 bg-surface-500/5 rounded border border-surface-500/10">
|
||||
<input type="checkbox" bind:checked={tmp__journal_obj.cfg_json.hide_personal} class="checkbox checkbox-sm" />
|
||||
<span class="text-xs font-bold">Hide Personal</span>
|
||||
</label>
|
||||
<label class="flex items-center space-x-2 cursor-pointer p-2 bg-surface-500/5 rounded border border-surface-500/10">
|
||||
<input type="checkbox" bind:checked={tmp__journal_obj.cfg_json.hide_professional} class="checkbox checkbox-sm" />
|
||||
<span class="text-xs font-bold">Hide Professional</span>
|
||||
</label>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Button Toggles (Restored) -->
|
||||
<section class="space-y-4 p-2">
|
||||
<h2 class="text-lg font-bold flex items-center gap-2 border-b border-surface-500/30 pb-2">
|
||||
<Settings size="1.2em" class="text-primary-500" />
|
||||
Entry Feature Buttons
|
||||
</h2>
|
||||
<div class="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-2">
|
||||
<label class="flex items-center gap-2 p-2 bg-surface-500/5 rounded border border-surface-500/10">
|
||||
<input type="checkbox" bind:checked={tmp__journal_obj.cfg_json.hide_btn_alert} class="checkbox checkbox-sm" />
|
||||
<span class="text-[10px] uppercase font-bold">Hide Alert</span>
|
||||
</label>
|
||||
<label class="flex items-center gap-2 p-2 bg-surface-500/5 rounded border border-surface-500/10">
|
||||
<input type="checkbox" bind:checked={tmp__journal_obj.cfg_json.hide_btn_private} class="checkbox checkbox-sm" />
|
||||
<span class="text-[10px] uppercase font-bold">Hide Private</span>
|
||||
</label>
|
||||
<label class="flex items-center gap-2 p-2 bg-surface-500/5 rounded border border-surface-500/10">
|
||||
<input type="checkbox" bind:checked={tmp__journal_obj.cfg_json.hide_btn_public} class="checkbox checkbox-sm" />
|
||||
<span class="text-[10px] uppercase font-bold">Hide Public</span>
|
||||
</label>
|
||||
<label class="flex items-center gap-2 p-2 bg-surface-500/5 rounded border border-surface-500/10">
|
||||
<input type="checkbox" bind:checked={tmp__journal_obj.cfg_json.hide_btn_personal} class="checkbox checkbox-sm" />
|
||||
<span class="text-[10px] uppercase font-bold">Hide Pers.</span>
|
||||
</label>
|
||||
<label class="flex items-center gap-2 p-2 bg-surface-500/5 rounded border border-surface-500/10">
|
||||
<input type="checkbox" bind:checked={tmp__journal_obj.cfg_json.hide_btn_professional} class="checkbox checkbox-sm" />
|
||||
<span class="text-[10px] uppercase font-bold">Hide Prof.</span>
|
||||
</label>
|
||||
<label class="flex items-center gap-2 p-2 bg-surface-500/5 rounded border border-surface-500/10">
|
||||
<input type="checkbox" bind:checked={tmp__journal_obj.cfg_json.hide_btn_template} class="checkbox checkbox-sm" />
|
||||
<span class="text-[10px] uppercase font-bold">Hide Templ.</span>
|
||||
</label>
|
||||
<label class="flex items-center gap-2 p-2 bg-surface-500/5 rounded border border-surface-500/10">
|
||||
<input type="checkbox" bind:checked={tmp__journal_obj.cfg_json.hide_copy_plain_md} class="checkbox checkbox-sm" />
|
||||
<span class="text-[10px] uppercase font-bold">Hide Copy MD</span>
|
||||
</label>
|
||||
<label class="flex items-center gap-2 p-2 bg-surface-500/5 rounded border border-surface-500/10">
|
||||
<input type="checkbox" bind:checked={tmp__journal_obj.cfg_json.hide_clone} class="checkbox checkbox-sm" />
|
||||
<span class="text-[10px] uppercase font-bold">Hide Clone</span>
|
||||
</label>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="space-y-4 p-2">
|
||||
<h2 class="text-lg font-bold flex items-center gap-2 border-b border-surface-500/30 pb-2">
|
||||
<Palette size="1.2em" class="text-primary-500" />
|
||||
Visual Theme
|
||||
<Layout size="1.2em" class="text-primary-500" />
|
||||
List Interactions
|
||||
</h2>
|
||||
<label class="label">
|
||||
<span class="text-sm font-bold opacity-70">Color Scheme</span>
|
||||
<select bind:value={tmp__journal_obj.cfg_json.color_scheme} class="select variant-form-material">
|
||||
<option value="">Default (Slate)</option>
|
||||
<option value="blue">Deep Blue</option>
|
||||
<option value="green">Nature Green</option>
|
||||
<option value="orange">Aether Orange</option>
|
||||
<option value="red">Warning Red</option>
|
||||
<option value="yellow">Caution Yellow</option>
|
||||
</select>
|
||||
</label>
|
||||
<div class="bg-surface-500/5 p-4 rounded-lg space-y-4">
|
||||
<label class="label">
|
||||
<span class="text-xs font-bold opacity-70">Expansion Trigger</span>
|
||||
<select bind:value={tmp__journal_obj.cfg_json.expand_li_content} class="select select-sm variant-form-material">
|
||||
<option value="click">Click to Expand</option>
|
||||
<option value="hover">Hover to Expand</option>
|
||||
</select>
|
||||
</label>
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||
<label class="label">
|
||||
<span class="text-xs font-bold opacity-70">List Max Height</span>
|
||||
<select bind:value={tmp__journal_obj.cfg_json.entry_li_max_height} class="select select-sm variant-form-material">
|
||||
<option value="">Default</option>
|
||||
<option value="max-h-16">Small (16)</option>
|
||||
<option value="max-h-32">Medium (32)</option>
|
||||
<option value="max-h-64">Large (64)</option>
|
||||
<option value="max-h-full">Full</option>
|
||||
</select>
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="text-xs font-bold opacity-70">Active Max Height</span>
|
||||
<select bind:value={tmp__journal_obj.cfg_json.entry_li_click_max_height} class="select select-sm variant-form-material">
|
||||
<option value="">Default</option>
|
||||
<option value="active:max-h-64">Large (64)</option>
|
||||
<option value="active:max-h-96">X-Large (96)</option>
|
||||
<option value="active:max-h-full">Full</option>
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user