Files
OSIT-AE-App-Svelte/src/routes/events/[event_id]/(launcher)/launcher_cfg.svelte
Scott Idem b543c8a930 chore: migrate all FA icons to Lucide (@lucide/svelte)
- Replaced all active FontAwesome <span class="fas fa-*"> icons with
  Lucide components across 145 files (excluding /idaa/ which is intentional)
- Fixed merge script bug: consolidated lucide-svelte imports into @lucide/svelte
- Replaced dynamic toggle patterns (fa-toggle-on/off) with ToggleRight/ToggleLeft
- Replaced fa-eye/fa-eye-slash with Eye/EyeOff
- Replaced fa-bug/fa-bug-slash with Bug/BugOff
- Replaced fa-sync fa-spin with RefreshCw + animate-spin
- Replaced fa-microchip with Cpu
- Fixed {@const} placement in element_manage_event_file_li.svelte
- Removed obsolete CSS hover rules for .unlock_icon/.lock_icon
- svelte-check: 0 errors, 0 warnings
2026-03-16 18:07:43 -04:00

259 lines
10 KiB
Svelte

<script lang="ts">
interface Props {
log_lvl?: number;
}
let { log_lvl = 0 }: Props = $props();
import {
ae_snip,
ae_loc,
ae_sess,
ae_api,
ae_trig,
slct,
slct_trigger,
time
} from '$lib/stores/ae_stores';
import {
events_loc,
events_sess,
events_slct,
events_trigger,
events_trig
} from '$lib/stores/ae_events_stores';
// Sub-components
import Launcher_Cfg_Native_OS from './cfg_components/launcher_cfg_native_os.svelte';
import Launcher_Cfg_Sync_Timers from './cfg_components/launcher_cfg_sync_timers.svelte';
import Launcher_Cfg_Health from './cfg_components/launcher_cfg_health.svelte';
import Launcher_Cfg_Updates from './cfg_components/launcher_cfg_updates.svelte';
import Launcher_Cfg_Controller from './cfg_components/launcher_cfg_controller.svelte';
import Launcher_Cfg_Screen_Saver from './cfg_components/launcher_cfg_screen_saver.svelte';
import Launcher_Cfg_App_Modes from './cfg_components/launcher_cfg_app_modes.svelte';
import Launcher_Cfg_Local_Actions from './cfg_components/launcher_cfg_local_actions.svelte';
import { Bug, Code, Monitor, Pencil, RefreshCw, Settings, SlidersHorizontal, X } from '@lucide/svelte';
// UI Tab State
// Tabs are audience-oriented:
// setup — what every onsite operator needs (mode preset, display, WS, screen saver)
// device — sync engine (all devices) + native/Electron OS controls (native or edit_mode)
// dev — developer/debug tools; only useful when edit_mode is on
let active_tab: 'setup' | 'device' | 'dev' = $state('setup');
/**
* Auto-Collapse Coordinator
* When a section is opened in 'auto' mode, collapse all other 'auto' sections.
* Pinned sections are ignored and remain open.
*/
function handle_section_expand(current_key: string) {
const launcher = $events_loc.launcher;
Object.keys(launcher).forEach((key) => {
if (
key.startsWith('section_state__') &&
key !== `section_state__${current_key}`
) {
if (launcher[key] === 'auto') {
launcher[key] = 'collapsed';
}
}
});
$events_loc.launcher = launcher; // Trigger store update
}
</script>
<div
class="
w-full max-w-full
flex flex-col gap-4 items-center justify-start
"
>
<div
class="w-full flex flex-row items-center justify-between border-b border-surface-500/20 pb-2"
>
<h2
class="text-center text-lg font-bold text-gray-700 dark:text-gray-200"
>
<Settings size="1em" class="mr-2 opacity-50" />
Launcher Configuration
</h2>
<div class="flex items-center gap-1">
<!-- Subtle Edit Mode toggle — intentionally low-key so kiosk operators
don't stumble on it, but accessible for setup/admin use.
Glows primary when active; nearly invisible when off. -->
<button
type="button"
onclick={() => ($ae_loc.edit_mode = !$ae_loc.edit_mode)}
class="btn btn-icon transition-all duration-300"
class:text-primary-500={$ae_loc.edit_mode}
class:opacity-20={!$ae_loc.edit_mode}
class:hover:opacity-60={!$ae_loc.edit_mode}
title="{$ae_loc.edit_mode ? 'Disable' : 'Enable'} Edit Mode"
>
<Pencil size="0.75em" />
<span class="sr-only">Toggle Edit Mode</span>
</button>
<button
type="button"
onclick={() => ($events_loc.launcher.hide_drawer__cfg = true)}
class="btn btn-icon dark:text-white hover:bg-surface-500/10 transition-colors"
>
<X size="1em" />
<span class="sr-only">Close Config</span>
</button>
</div>
</div>
<!-- Category Tabs -->
<!-- Dev tab is only shown when Edit Mode is active — keeps the UI uncluttered
for onsite operators who never need those tools. Edit Mode is toggled via
the pencil icon in the header above. -->
<div
class="w-full gap-1 bg-surface-500/10 p-1 rounded-lg"
class:grid={true}
class:grid-cols-2={!$ae_loc.edit_mode}
class:grid-cols-3={$ae_loc.edit_mode}
>
<button
type="button"
onclick={() => (active_tab = 'setup')}
class="btn btn-sm text-[10px] uppercase font-bold transition-all"
class:preset-filled-primary={active_tab === 'setup'}
class:preset-tonal-surface={active_tab !== 'setup'}
title="Display presets, interface toggles, WS controller, screen saver"
>
<SlidersHorizontal size="0.85em" class="mr-1" /> Setup
</button>
<button
type="button"
onclick={() => (active_tab = 'device')}
class="btn btn-sm text-[10px] uppercase font-bold transition-all"
class:preset-filled-primary={active_tab === 'device'}
class:preset-tonal-surface={active_tab !== 'device'}
title="Sync engine, device health &amp; native OS controls"
>
<Monitor size="0.85em" class="mr-1" /> Device
</button>
{#if $ae_loc.edit_mode}
<button
type="button"
onclick={() => (active_tab = 'dev')}
class="btn btn-sm text-[10px] uppercase font-bold transition-all"
class:preset-filled-warning={active_tab === 'dev'}
class:preset-tonal-surface={active_tab !== 'dev'}
title="Developer &amp; debug tools"
>
<Code size="0.85em" class="mr-1" /> Dev
</button>
{/if}
</div>
<!-- Tab Content -->
<div class="w-full flex flex-col gap-2 min-h-[400px]">
<!-- SETUP: everything onsite operators need day-to-day -->
{#if active_tab === 'setup'}
<div class="animate-in fade-in slide-in-from-left-2 duration-300 flex flex-col gap-2">
<!-- Mode preset is the #1 onsite action — give it prominent placement -->
<Launcher_Cfg_App_Modes
on_expand={() => handle_section_expand('app_modes')}
/>
<Launcher_Cfg_Controller
on_expand={() => handle_section_expand('controller')}
/>
<Launcher_Cfg_Screen_Saver
on_expand={() => handle_section_expand('screen_saver')}
/>
</div>
{/if}
<!-- DEVICE: sync engine first (all devices) + native OS controls (native or edit_mode preview) -->
{#if active_tab === 'device'}
<div class="animate-in fade-in slide-in-from-bottom-2 duration-300 flex flex-col gap-2">
<!-- Sync pause/timers — relevant to every device, not just native -->
<Launcher_Cfg_Sync_Timers
on_expand={() => handle_section_expand('sync_timers')}
/>
<!-- Native sections: always in Electron; visible in edit_mode for dev preview.
electron_relay.ts guards all calls — safe to import/render without Electron. -->
{#if $ae_loc.is_native || $ae_loc.edit_mode}
<Launcher_Cfg_Health
on_expand={() => handle_section_expand('health')}
/>
<Launcher_Cfg_Native_OS
on_expand={() => handle_section_expand('native_os')}
/>
{#if $ae_loc.is_native}
<Launcher_Cfg_Updates
on_expand={() => handle_section_expand('updates')}
/>
{/if}
{:else}
<div class="py-3 text-center opacity-40 italic text-xs flex flex-col gap-1 items-center">
<Monitor size="1.2em" class="opacity-30" />
<p>Native OS controls available in Aether Desktop.</p>
<p class="text-[9px]">Enable Edit Mode to preview.</p>
</div>
{/if}
</div>
{/if}
<!-- DEV: developer/debug tools — only reachable when Edit Mode is on -->
{#if active_tab === 'dev' && $ae_loc.edit_mode}
<div class="animate-in fade-in slide-in-from-right-2 duration-300 flex flex-col gap-2">
<Launcher_Cfg_Local_Actions
on_expand={() => handle_section_expand('local_actions')}
/>
</div>
{/if}
</div>
<!-- Global Actions Footer -->
<div
class="w-full flex flex-col gap-2 border-t border-surface-500/20 pt-4 mt-auto"
>
<div class="grid grid-cols-2 gap-2">
<!-- Close button — always visible in lower-left as a second dismissal point.
Useful in kiosk/iframe mode where the top-right close btn may scroll out of view. -->
<button
type="button"
onclick={() => ($events_loc.launcher.hide_drawer__cfg = true)}
class="btn btn-sm preset-tonal-surface hover:preset-filled-surface-500 transition-all"
>
<X size="0.85em" class="mr-1" />
Close
</button>
<button
type="button"
onclick={() => location.reload()}
class="btn btn-sm preset-tonal-secondary hover:preset-filled-secondary-500 transition-all"
>
<RefreshCw size="0.85em" class="mr-1" />
Reload
</button>
</div>
{#if $ae_loc.edit_mode}
<button
type="button"
onclick={() =>
($events_loc.launcher.hide_drawer__debug = false)}
class="btn btn-sm preset-tonal-warning hover:preset-filled-warning-500 transition-all w-full"
>
<Bug size="0.85em" class="mr-1" />
Debug Panel
</button>
{/if}
<p
class="text-[9px] text-center opacity-40 uppercase font-bold tracking-widest mt-2"
>
Aether Platform &bull; Events Launcher v3.0
</p>
</div>
</div>