817 lines
38 KiB
Svelte
817 lines
38 KiB
Svelte
<script lang="ts">
|
|
import { untrack } from 'svelte';
|
|
/**
|
|
* ae_comp__journal_obj_id_edit.svelte
|
|
* Standardized Journal-level configuration.
|
|
* Restored missing visibility and button toggles.
|
|
*/
|
|
import {
|
|
BetweenVerticalEnd,
|
|
BetweenVerticalStart,
|
|
BookHeart,
|
|
BookOpenText,
|
|
BriefcaseBusiness,
|
|
CalendarClock,
|
|
Check,
|
|
CodeXml,
|
|
Copy,
|
|
Database,
|
|
Expand,
|
|
Eye,
|
|
EyeOff,
|
|
FileDown,
|
|
FilePlus,
|
|
FileUp,
|
|
FingerprintPattern,
|
|
Globe,
|
|
Layout,
|
|
LockKeyhole,
|
|
MessageSquareWarning,
|
|
Minus,
|
|
MonitorPlay,
|
|
MousePointerClick,
|
|
Palette,
|
|
Plus,
|
|
Settings,
|
|
ShieldCheck,
|
|
Siren,
|
|
Target,
|
|
Trash2,
|
|
X,
|
|
Zap
|
|
} from '@lucide/svelte';
|
|
import { Modal } from 'flowbite-svelte';
|
|
import { goto } from '$app/navigation';
|
|
|
|
// *** Import Aether specific variables and functions
|
|
import { ae_loc, ae_api } from '$lib/stores/ae_stores';
|
|
import {
|
|
journals_loc,
|
|
journals_sess,
|
|
journals_slct
|
|
} from '$lib/ae_journals/ae_journals_stores';
|
|
import { journals_func } from '$lib/ae_journals/ae_journals_functions';
|
|
import AE_Comp_Editor_CodeMirror from '$lib/elements/element_editor_codemirror.svelte';
|
|
|
|
interface Props {
|
|
log_lvl?: number;
|
|
lq__journal_obj: any;
|
|
show?: boolean;
|
|
on_new_entry?: () => void;
|
|
on_show_export?: () => void;
|
|
on_show_import?: () => void;
|
|
}
|
|
|
|
let {
|
|
log_lvl = $bindable(0),
|
|
lq__journal_obj,
|
|
show = $bindable(false),
|
|
on_new_entry,
|
|
on_show_export,
|
|
on_show_import
|
|
}: Props = $props();
|
|
|
|
// *** Internal State
|
|
let tab: 'actions' | 'general' | 'security' | 'ui' | 'json' = $state('actions');
|
|
let tmp__journal_obj: any = $state({});
|
|
|
|
// Deep copy on mount or when lq changes to ensure we have a working copy
|
|
$effect(() => {
|
|
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 = {};
|
|
}
|
|
});
|
|
}
|
|
});
|
|
|
|
async function handle_update_journal(close_modal: boolean = true) {
|
|
if (!tmp__journal_obj.name || !tmp__journal_obj.type_code) {
|
|
alert('Please provide both name and type for the journal.');
|
|
return;
|
|
}
|
|
|
|
try {
|
|
// DEFINITIVE BASE TABLE COLUMNS ONLY
|
|
const data_kv = {
|
|
name: tmp__journal_obj.name,
|
|
short_name: tmp__journal_obj.short_name,
|
|
type_code: tmp__journal_obj.type_code,
|
|
description: tmp__journal_obj.description,
|
|
summary: tmp__journal_obj.summary,
|
|
outline: tmp__journal_obj.outline,
|
|
passcode: tmp__journal_obj.passcode,
|
|
private_passcode: tmp__journal_obj.private_passcode,
|
|
public_passcode: tmp__journal_obj.public_passcode,
|
|
passcode_timeout: tmp__journal_obj.passcode_timeout,
|
|
auth_key: tmp__journal_obj.auth_key,
|
|
allow_auth: tmp__journal_obj.allow_auth,
|
|
cfg_json: tmp__journal_obj.cfg_json,
|
|
data_json: tmp__journal_obj.data_json,
|
|
enable: tmp__journal_obj.enable,
|
|
hide: tmp__journal_obj.hide,
|
|
priority: tmp__journal_obj.priority,
|
|
sort: tmp__journal_obj.sort,
|
|
group: tmp__journal_obj.group,
|
|
notes: tmp__journal_obj.notes,
|
|
alert: tmp__journal_obj.alert,
|
|
alert_msg: tmp__journal_obj.alert_msg,
|
|
archive_on: tmp__journal_obj.archive_on,
|
|
default_private: tmp__journal_obj.default_private,
|
|
default_public: tmp__journal_obj.default_public,
|
|
default_personal: tmp__journal_obj.default_personal,
|
|
default_professional: tmp__journal_obj.default_professional
|
|
};
|
|
|
|
await journals_func.update_ae_obj__journal({
|
|
api_cfg: $ae_api,
|
|
journal_id: $lq__journal_obj?.journal_id,
|
|
data_kv: data_kv,
|
|
log_lvl: log_lvl
|
|
});
|
|
|
|
if (close_modal) show = false;
|
|
} catch (error) {
|
|
console.error('Error updating journal:', error);
|
|
if (close_modal) alert('Failed to update journal.');
|
|
}
|
|
}
|
|
|
|
async function delete_journal() {
|
|
if (
|
|
confirm(
|
|
`CRITICAL WARNING: Are you sure you want to delete the journal "${$lq__journal_obj.name}"? This will delete all entries associated with it.`
|
|
)
|
|
) {
|
|
try {
|
|
await journals_func.delete_ae_obj_id__journal({
|
|
api_cfg: $ae_api,
|
|
journal_id: $lq__journal_obj?.journal_id,
|
|
log_lvl: log_lvl
|
|
});
|
|
alert('Journal deleted successfully!');
|
|
goto('/journals');
|
|
} catch (error) {
|
|
console.error('Error deleting journal:', error);
|
|
alert('Failed to delete journal.');
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<Modal
|
|
bind:open={show}
|
|
autoclose={false}
|
|
dismissable={false}
|
|
placement="top-center"
|
|
size="xl"
|
|
class="relative mx-auto flex w-full flex-col rounded-lg border border-orange-300 bg-white text-gray-800 shadow-xl dark:border-orange-700 dark:bg-gray-800 dark:text-gray-200"
|
|
headerClass="flex flex-row gap-2 items-center justify-between w-full bg-orange-100 dark:bg-orange-900 p-4 rounded-t-lg border-b border-orange-200 dark:border-orange-800"
|
|
footerClass="flex flex-row gap-2 items-center justify-center w-full bg-orange-100 dark:bg-orange-900 p-4 rounded-b-lg border-t border-orange-200 dark:border-orange-800">
|
|
{#snippet header()}
|
|
<h3 class="flex flex-1 items-center gap-2 text-lg font-bold">
|
|
<Settings class="text-primary-500" />
|
|
<span>Journal Config: {$lq__journal_obj?.name ?? '--'}</span>
|
|
</h3>
|
|
<button
|
|
type="button"
|
|
class="btn-icon btn-icon-sm preset-tonal-surface ml-2"
|
|
onclick={() => (show = false)}>
|
|
<X size="1.1em" />
|
|
</button>
|
|
{/snippet}
|
|
|
|
<div class="h-[75vh] space-y-6 overflow-y-auto px-4 py-2">
|
|
<!-- Navigation Tabs -->
|
|
<div
|
|
class="bg-surface-500/10 sticky top-0 z-10 mx-auto mb-4 flex max-w-fit justify-center gap-1 rounded-lg p-1 backdrop-blur-sm">
|
|
<button
|
|
type="button"
|
|
class="btn btn-sm transition-all {tab === 'actions'
|
|
? 'preset-filled-primary'
|
|
: 'preset-tonal-surface'}"
|
|
onclick={() => (tab = 'actions')}>
|
|
<Zap size="1.1em" class="mr-1" /> Quick Actions
|
|
</button>
|
|
<button
|
|
type="button"
|
|
class="btn btn-sm transition-all {tab === 'general'
|
|
? 'preset-filled-primary'
|
|
: 'preset-tonal-surface'}"
|
|
onclick={() => (tab = 'general')}>
|
|
<Layout size="1.1em" class="mr-1" /> General
|
|
</button>
|
|
<button
|
|
type="button"
|
|
class="btn btn-sm transition-all {tab === 'security'
|
|
? 'preset-filled-primary'
|
|
: 'preset-tonal-surface'}"
|
|
onclick={() => (tab = 'security')}>
|
|
<ShieldCheck size="1.1em" class="mr-1" /> Status & Security
|
|
</button>
|
|
<button
|
|
type="button"
|
|
class="btn btn-sm transition-all {tab === 'ui'
|
|
? 'preset-filled-primary'
|
|
: 'preset-tonal-surface'}"
|
|
onclick={() => (tab = 'ui')}>
|
|
<Palette size="1.1em" class="mr-1" /> UI/Visuals
|
|
</button>
|
|
<button
|
|
type="button"
|
|
class="btn btn-sm transition-all {tab === 'json'
|
|
? 'preset-filled-primary'
|
|
: 'preset-tonal-surface'}"
|
|
onclick={() => (tab = 'json')}>
|
|
<CodeXml size="1.1em" class="mr-1" /> JSON
|
|
</button>
|
|
</div>
|
|
|
|
{#if tab === 'actions'}
|
|
<div class="animate-in fade-in space-y-6 duration-300">
|
|
<section class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
|
<button
|
|
type="button"
|
|
class="btn preset-tonal-secondary w-full py-4 text-lg font-bold"
|
|
onclick={() => {
|
|
show = false;
|
|
on_new_entry?.();
|
|
}}>
|
|
<FilePlus size="1.5em" class="mr-2" /> New Journal Entry
|
|
</button>
|
|
<button
|
|
type="button"
|
|
class="btn preset-tonal-surface w-full py-4"
|
|
onclick={() => {
|
|
show = false;
|
|
on_show_export?.();
|
|
}}>
|
|
<FileDown size="1.5em" class="mr-2" /> Export Entries
|
|
</button>
|
|
<button
|
|
type="button"
|
|
class="btn preset-tonal-surface w-full py-4"
|
|
onclick={() => {
|
|
show = false;
|
|
on_show_import?.();
|
|
}}>
|
|
<FileUp size="1.5em" class="mr-2" /> Import Entries
|
|
</button>
|
|
</section>
|
|
</div>
|
|
{:else if tab === 'general'}
|
|
<div class="animate-in fade-in space-y-6 duration-300">
|
|
<!-- Core Meta -->
|
|
<section class="grid grid-cols-1 gap-4 p-2">
|
|
<label class="label flex flex-col items-start gap-1">
|
|
<span class="text-sm font-bold opacity-70"
|
|
>Journal Name</span>
|
|
<input
|
|
type="text"
|
|
bind:value={tmp__journal_obj.name}
|
|
class="input"
|
|
placeholder="e.g. Personal Log" />
|
|
</label>
|
|
<label class="label flex flex-col items-start gap-1">
|
|
<span class="text-sm font-bold opacity-70"
|
|
>Description (Markdown)</span>
|
|
<div class="w-full">
|
|
{#if tmp__journal_obj?.cfg_json?.pref_editor === 'codemirror'}
|
|
<AE_Comp_Editor_CodeMirror
|
|
bind:content={tmp__journal_obj.description}
|
|
language="markdown"
|
|
theme_mode={$ae_loc.theme_mode}
|
|
placeholder="Describe the purpose of this journal..."
|
|
class_li="rounded-lg border border-surface-500/20" />
|
|
{:else}
|
|
<textarea
|
|
bind:value={tmp__journal_obj.description}
|
|
class="textarea h-32"
|
|
placeholder="Describe the purpose of this journal..."
|
|
></textarea>
|
|
{/if}
|
|
</div>
|
|
</label>
|
|
<div class="grid grid-cols-2 gap-4">
|
|
<label class="label flex flex-col items-start gap-1">
|
|
<span class="text-sm font-bold opacity-70"
|
|
>Type</span>
|
|
<select
|
|
bind:value={tmp__journal_obj.type_code}
|
|
class="select">
|
|
{#each $journals_loc.journal.type_code_li as type (type.code)}
|
|
<option value={type.code}
|
|
>{type.name}</option>
|
|
{/each}
|
|
</select>
|
|
</label>
|
|
<label class="label flex flex-col items-start gap-1">
|
|
<span class="text-sm font-bold opacity-70"
|
|
>Journal Group (text)</span>
|
|
<input
|
|
type="text"
|
|
bind:value={tmp__journal_obj.group}
|
|
class="input"
|
|
placeholder="Standard" />
|
|
</label>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Categories -->
|
|
<section class="space-y-4 p-2">
|
|
<h2
|
|
class="border-surface-500/30 flex items-center gap-2 border-b pb-2 text-lg font-bold">
|
|
<MonitorPlay size="1em" class="text-primary-500" />
|
|
Journal Categories
|
|
</h2>
|
|
<div
|
|
class="bg-surface-500/5 border-surface-500/10 space-y-2 rounded-lg border p-4">
|
|
{#each tmp__journal_obj?.cfg_json?.category_li ?? [] as category, i (category.code ?? i)}
|
|
<div class="flex items-center gap-2">
|
|
<input
|
|
type="text"
|
|
bind:value={category.code}
|
|
class="input input-sm w-32"
|
|
placeholder="Code" />
|
|
<input
|
|
type="text"
|
|
bind:value={category.name}
|
|
class="input input-sm grow"
|
|
placeholder="Display Name" />
|
|
<button
|
|
type="button"
|
|
class="btn-icon btn-icon-sm preset-tonal-error"
|
|
onclick={() => {
|
|
tmp__journal_obj.cfg_json.category_li.splice(
|
|
i,
|
|
1
|
|
);
|
|
}}>
|
|
<Minus size="1em" />
|
|
</button>
|
|
</div>
|
|
{/each}
|
|
<button
|
|
type="button"
|
|
class="btn btn-sm preset-tonal-primary mt-2 w-full"
|
|
onclick={() => {
|
|
if (!tmp__journal_obj.cfg_json.category_li)
|
|
tmp__journal_obj.cfg_json.category_li = [];
|
|
tmp__journal_obj.cfg_json.category_li.push({
|
|
code: '',
|
|
name: ''
|
|
});
|
|
}}>
|
|
<Plus size="1em" class="mr-1" /> Add Category
|
|
</button>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
{:else if tab === 'security'}
|
|
<div class="animate-in fade-in space-y-6 duration-300">
|
|
<!-- Status & Lifecycle -->
|
|
<section class="space-y-4 p-2">
|
|
<h2
|
|
class="border-surface-500/30 flex items-center gap-2 border-b pb-2 text-lg font-bold">
|
|
<FingerprintPattern size="1.2em" class="text-primary-500" />
|
|
Status & Lifecycle
|
|
</h2>
|
|
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
|
<label
|
|
class="bg-surface-500/5 border-surface-500/10 hover:bg-surface-500/10 flex cursor-pointer items-center space-x-3 rounded-lg border p-3 transition-colors">
|
|
<input
|
|
type="checkbox"
|
|
bind:checked={tmp__journal_obj.enable}
|
|
onchange={() => handle_update_journal(false)}
|
|
class="checkbox checkbox-primary" />
|
|
<div class="flex flex-col">
|
|
<span class="font-bold">Enabled</span>
|
|
<span class="text-xs opacity-60"
|
|
>Allow access to this journal</span>
|
|
</div>
|
|
</label>
|
|
<label
|
|
class="bg-surface-500/5 border-surface-500/10 hover:bg-surface-500/10 flex cursor-pointer items-center space-x-3 rounded-lg border p-3 transition-colors">
|
|
<input
|
|
type="checkbox"
|
|
bind:checked={tmp__journal_obj.hide}
|
|
onchange={() => handle_update_journal(false)}
|
|
class="checkbox checkbox-primary" />
|
|
<div class="flex flex-col">
|
|
<span class="font-bold">Hidden</span>
|
|
<span class="text-xs opacity-60"
|
|
>Hide from standard lists</span>
|
|
</div>
|
|
</label>
|
|
<label
|
|
class="bg-surface-500/5 border-surface-500/10 hover:bg-surface-500/10 flex cursor-pointer items-center space-x-3 rounded-lg border p-3 transition-colors">
|
|
<input
|
|
type="checkbox"
|
|
bind:checked={tmp__journal_obj.priority}
|
|
onchange={() => handle_update_journal(false)}
|
|
class="checkbox checkbox-primary" />
|
|
<div class="flex flex-col">
|
|
<span class="font-bold">Priority Journal</span>
|
|
<span class="text-xs opacity-60"
|
|
>Star or pin to top</span>
|
|
</div>
|
|
</label>
|
|
<div
|
|
class="bg-surface-500/5 border-surface-500/10 flex items-center justify-between rounded-lg border p-3">
|
|
<div class="flex flex-col">
|
|
<span class="text-sm font-bold"
|
|
>Sort Order</span>
|
|
<span class="text-xs opacity-60"
|
|
>Manual list position</span>
|
|
</div>
|
|
<div class="flex items-center gap-2">
|
|
<button
|
|
type="button"
|
|
class="btn-icon btn-icon-sm preset-tonal-surface"
|
|
onclick={() => {
|
|
tmp__journal_obj.sort =
|
|
(tmp__journal_obj.sort ?? 0) - 1;
|
|
handle_update_journal(false);
|
|
}}><Minus size="1em" /></button>
|
|
<span
|
|
class="w-8 text-center font-mono text-lg font-bold"
|
|
>{tmp__journal_obj.sort ?? 0}</span>
|
|
<button
|
|
type="button"
|
|
class="btn-icon btn-icon-sm preset-tonal-surface"
|
|
onclick={() => {
|
|
tmp__journal_obj.sort =
|
|
(tmp__journal_obj.sort ?? 0) + 1;
|
|
handle_update_journal(false);
|
|
}}><Plus size="1em" /></button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Encryption Passcodes -->
|
|
<section class="space-y-4 p-2">
|
|
<h2
|
|
class="border-surface-500/30 flex items-center gap-2 border-b pb-2 text-lg font-bold">
|
|
<LockKeyhole size="1.2em" class="text-primary-500" />
|
|
Encryption Passcodes
|
|
</h2>
|
|
<div
|
|
class="bg-warning-500/10 border-warning-500/30 space-y-4 rounded-lg border p-4 shadow-inner">
|
|
<label class="label">
|
|
<span
|
|
class="text-xs font-bold tracking-wider uppercase opacity-70"
|
|
>Primary Passcode (Stored)</span>
|
|
<div class="flex gap-2">
|
|
<input
|
|
type="password"
|
|
bind:value={tmp__journal_obj.passcode}
|
|
class="input grow"
|
|
placeholder="Module-level passcode" />
|
|
<FingerprintPattern class="opacity-30" />
|
|
</div>
|
|
</label>
|
|
<label class="label">
|
|
<span
|
|
class="text-xs font-bold tracking-wider uppercase opacity-70"
|
|
>Private Passcode (Double Encryption)</span>
|
|
<div class="flex gap-2">
|
|
<input
|
|
type="password"
|
|
bind:value={
|
|
tmp__journal_obj.private_passcode
|
|
}
|
|
class="input grow"
|
|
placeholder="User-level secret" />
|
|
<ShieldCheck class="opacity-30" />
|
|
</div>
|
|
</label>
|
|
<div
|
|
class="text-warning-700 dark:text-warning-300 text-[10px] italic">
|
|
* Note: Passcodes are used locally for E2EE. Primary
|
|
is often stored in the DB, while Private should
|
|
remain known only to you.
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="pt-8">
|
|
<button
|
|
type="button"
|
|
class="btn btn-sm preset-tonal-error hover:preset-filled-error-500 w-full shadow-lg"
|
|
onclick={delete_journal}>
|
|
<Trash2 size="1.1em" class="mr-2" /> Delete Entire Journal
|
|
</button>
|
|
</section>
|
|
</div>
|
|
{:else if tab === 'ui'}
|
|
<div class="animate-in fade-in space-y-8 duration-300">
|
|
<section class="space-y-4 p-2">
|
|
<h2
|
|
class="border-surface-500/30 flex items-center gap-2 border-b pb-2 text-lg font-bold">
|
|
<MonitorPlay size="1.2em" class="text-primary-500" />
|
|
Default View Modes
|
|
</h2>
|
|
<div
|
|
class="bg-surface-500/5 border-surface-500/10 grid grid-cols-1 gap-6 rounded-lg border p-4 md:grid-cols-2">
|
|
<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">
|
|
<option value="rendered"
|
|
>Rendered HTML (Default)</option>
|
|
<option value="plain">Plain Text</option>
|
|
<option value="codemirror"
|
|
>CodeMirror (Syntax)</option>
|
|
</select>
|
|
</label>
|
|
<label class="label">
|
|
<span class="text-sm font-bold opacity-70"
|
|
>Preferred Editor</span>
|
|
<select
|
|
bind:value={
|
|
tmp__journal_obj.cfg_json.pref_editor
|
|
}
|
|
class="select">
|
|
<option value="textarea"
|
|
>Standard Textarea</option>
|
|
<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">
|
|
<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">
|
|
<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="border-surface-500/30 flex items-center gap-2 border-b pb-2 text-lg font-bold">
|
|
<Eye size="1.2em" class="text-primary-500" />
|
|
Entry Visibility (Global)
|
|
</h2>
|
|
<div
|
|
class="grid grid-cols-1 gap-2 sm:grid-cols-2 lg:grid-cols-3">
|
|
<label
|
|
class="bg-surface-500/5 border-surface-500/10 flex cursor-pointer items-center space-x-2 rounded border p-2">
|
|
<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="bg-surface-500/5 border-surface-500/10 flex cursor-pointer items-center space-x-2 rounded border p-2">
|
|
<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="bg-surface-500/5 border-surface-500/10 flex cursor-pointer items-center space-x-2 rounded border p-2">
|
|
<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="border-surface-500/30 flex items-center gap-2 border-b pb-2 text-lg font-bold">
|
|
<Settings size="1.2em" class="text-primary-500" />
|
|
Entry Feature Buttons
|
|
</h2>
|
|
<div
|
|
class="grid grid-cols-2 gap-2 sm:grid-cols-3 lg:grid-cols-4">
|
|
<label
|
|
class="bg-surface-500/5 border-surface-500/10 flex items-center gap-2 rounded border p-2">
|
|
<input
|
|
type="checkbox"
|
|
bind:checked={
|
|
tmp__journal_obj.cfg_json.hide_btn_alert
|
|
}
|
|
class="checkbox checkbox-sm" />
|
|
<span class="text-[10px] font-bold uppercase"
|
|
>Hide Alert</span>
|
|
</label>
|
|
<label
|
|
class="bg-surface-500/5 border-surface-500/10 flex items-center gap-2 rounded border p-2">
|
|
<input
|
|
type="checkbox"
|
|
bind:checked={
|
|
tmp__journal_obj.cfg_json.hide_btn_private
|
|
}
|
|
class="checkbox checkbox-sm" />
|
|
<span class="text-[10px] font-bold uppercase"
|
|
>Hide Private</span>
|
|
</label>
|
|
<label
|
|
class="bg-surface-500/5 border-surface-500/10 flex items-center gap-2 rounded border p-2">
|
|
<input
|
|
type="checkbox"
|
|
bind:checked={
|
|
tmp__journal_obj.cfg_json.hide_btn_public
|
|
}
|
|
class="checkbox checkbox-sm" />
|
|
<span class="text-[10px] font-bold uppercase"
|
|
>Hide Public</span>
|
|
</label>
|
|
<label
|
|
class="bg-surface-500/5 border-surface-500/10 flex items-center gap-2 rounded border p-2">
|
|
<input
|
|
type="checkbox"
|
|
bind:checked={
|
|
tmp__journal_obj.cfg_json.hide_btn_personal
|
|
}
|
|
class="checkbox checkbox-sm" />
|
|
<span class="text-[10px] font-bold uppercase"
|
|
>Hide Pers.</span>
|
|
</label>
|
|
<label
|
|
class="bg-surface-500/5 border-surface-500/10 flex items-center gap-2 rounded border p-2">
|
|
<input
|
|
type="checkbox"
|
|
bind:checked={
|
|
tmp__journal_obj.cfg_json
|
|
.hide_btn_professional
|
|
}
|
|
class="checkbox checkbox-sm" />
|
|
<span class="text-[10px] font-bold uppercase"
|
|
>Hide Prof.</span>
|
|
</label>
|
|
<label
|
|
class="bg-surface-500/5 border-surface-500/10 flex items-center gap-2 rounded border p-2">
|
|
<input
|
|
type="checkbox"
|
|
bind:checked={
|
|
tmp__journal_obj.cfg_json.hide_btn_template
|
|
}
|
|
class="checkbox checkbox-sm" />
|
|
<span class="text-[10px] font-bold uppercase"
|
|
>Hide Templ.</span>
|
|
</label>
|
|
<label
|
|
class="bg-surface-500/5 border-surface-500/10 flex items-center gap-2 rounded border p-2">
|
|
<input
|
|
type="checkbox"
|
|
bind:checked={
|
|
tmp__journal_obj.cfg_json.hide_copy_plain_md
|
|
}
|
|
class="checkbox checkbox-sm" />
|
|
<span class="text-[10px] font-bold uppercase"
|
|
>Hide Copy MD</span>
|
|
</label>
|
|
<label
|
|
class="bg-surface-500/5 border-surface-500/10 flex items-center gap-2 rounded border p-2">
|
|
<input
|
|
type="checkbox"
|
|
bind:checked={
|
|
tmp__journal_obj.cfg_json.hide_clone
|
|
}
|
|
class="checkbox checkbox-sm" />
|
|
<span class="text-[10px] font-bold uppercase"
|
|
>Hide Clone</span>
|
|
</label>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="space-y-4 p-2">
|
|
<h2
|
|
class="border-surface-500/30 flex items-center gap-2 border-b pb-2 text-lg font-bold">
|
|
<Layout size="1.2em" class="text-primary-500" />
|
|
List Interactions
|
|
</h2>
|
|
<div class="bg-surface-500/5 space-y-4 rounded-lg p-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">
|
|
<option value="click">Click to Expand</option>
|
|
<option value="hover">Hover to Expand</option>
|
|
</select>
|
|
</label>
|
|
<div class="grid grid-cols-1 gap-4 sm:grid-cols-2">
|
|
<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">
|
|
<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">
|
|
<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>
|
|
{:else if tab === 'json'}
|
|
<div class="h-full min-h-[400px]">
|
|
<AE_Comp_Editor_CodeMirror
|
|
readonly={true}
|
|
content={JSON.stringify(tmp__journal_obj, null, 2)}
|
|
theme_mode={$ae_loc.theme_mode}
|
|
class_li="rounded-lg border border-surface-500/30" />
|
|
</div>
|
|
{/if}
|
|
</div>
|
|
|
|
{#snippet footer()}
|
|
<div class="flex gap-4">
|
|
<button
|
|
type="button"
|
|
class="btn preset-tonal-surface min-w-[100px] font-bold"
|
|
onclick={() => (show = false)}>
|
|
<X size="1.2em" class="mr-2" /> Cancel
|
|
</button>
|
|
<button
|
|
type="button"
|
|
class="btn preset-filled-primary min-w-[120px] font-bold"
|
|
onclick={() => handle_update_journal(true)}>
|
|
<Check size="1.2em" class="mr-2" /> Save Changes
|
|
</button>
|
|
</div>
|
|
{/snippet}
|
|
</Modal>
|