pres_mgmt: config schema cleanup phase 2

- Add show__session_qr + show__presenter_qr to PressMgmtRemoteCfg and sync function;
  QR toggles now gated on remote admin enable (trusted_access can still override)
- Remove hide__launcher_link_legacy everywhere (Flask launcher fully retired)
- Remove limit__options (YAGNI)
- Implement limit__navigation: hides Session Search nav link for non-trusted users
- Wire hide__report_kv into reports page: all 8 report tabs now use synced store
  with canonical slug names and edit_mode bypass; config UI now uses structured
  toggles instead of raw JSON textarea
- Gate hide__launcher_link local toggle on show__launcher_link || trusted_access
- Config UI: add show__session_qr + show__presenter_qr to opt-in features section
- Menu opts: add Query Limits / Display & Search / Staff Options section labels
- Bump AE_PRES_MGMT_LOC_VERSION to 2 (schema change forces localStorage reset)
- svelte-check: 0 errors
This commit is contained in:
Scott Idem
2026-06-16 11:39:47 -04:00
parent a47a2103eb
commit 2364c0edfb
14 changed files with 204 additions and 273 deletions

View File

@@ -1054,14 +1054,16 @@ export function sync_config__event_pres_mgmt({
// Launcher links (show__ in remote → invert to hide__ in local display state) // Launcher links (show__ in remote → invert to hide__ in local display state)
loc.hide__launcher_link = loc.hide__launcher_link =
!(pres_mgmt_cfg_remote?.show__launcher_link ?? false); !(pres_mgmt_cfg_remote?.show__launcher_link ?? false);
// Legacy Flask launcher is retired — always hide regardless of remote config
loc.hide__launcher_link_legacy = true; // QR code sections (off by default; admin enables per-event)
loc.show__session_qr =
pres_mgmt_cfg_remote?.show__session_qr ?? false;
loc.show__presenter_qr =
pres_mgmt_cfg_remote?.show__presenter_qr ?? false;
// Navigation / UI constraints // Navigation / UI constraints
loc.limit__navigation = loc.limit__navigation =
pres_mgmt_cfg_remote?.limit__navigation ?? false; pres_mgmt_cfg_remote?.limit__navigation ?? false;
loc.limit__options =
pres_mgmt_cfg_remote?.limit__options ?? false;
} }
} }

View File

@@ -58,6 +58,10 @@ export interface PressMgmtRemoteCfg {
// (the overall "is POC used at all" master switch) — that one wins if set, // (the overall "is POC used at all" master switch) — that one wins if set,
// see sync_config__event_pres_mgmt() and the session list wrapper usages. // see sync_config__event_pres_mgmt() and the session list wrapper usages.
show__session_li_poc_field: boolean; show__session_li_poc_field: boolean;
// QR code sections (off by default; Trusted Access users can override locally
// if the admin has enabled the feature for the event)
show__session_qr: boolean;
show__presenter_qr: boolean;
// Requirements // Requirements
require__presenter_agree: boolean; require__presenter_agree: boolean;
@@ -65,7 +69,6 @@ export interface PressMgmtRemoteCfg {
// Navigation / UI constraints // Navigation / UI constraints
limit__navigation: boolean; limit__navigation: boolean;
limit__options: boolean;
// File upload options (null = use system default) // File upload options (null = use system default)
file_purpose_option_kv: Record< file_purpose_option_kv: Record<
@@ -157,7 +160,6 @@ export interface PresMgmtLocState {
// (overwritten when lock_config=true), see sync_config__event_pres_mgmt(). // (overwritten when lock_config=true), see sync_config__event_pres_mgmt().
show__session_li_poc_field: boolean; show__session_li_poc_field: boolean;
// Launcher/location links in session list // Launcher/location links in session list
hide__launcher_link_legacy: boolean; // Flask/legacy launcher
hide__launcher_link: boolean; // SvelteKit launcher hide__launcher_link: boolean; // SvelteKit launcher
hide__location_link: boolean; hide__location_link: boolean;
show__direct_download: boolean; show__direct_download: boolean;
@@ -201,10 +203,11 @@ export interface PresMgmtLocState {
show__copy_access_link: boolean; show__copy_access_link: boolean;
show__email_access_link: boolean; show__email_access_link: boolean;
show__launcher_link: boolean; show__launcher_link: boolean;
show__session_qr: boolean;
show__presenter_qr: boolean;
require__presenter_agree: boolean; require__presenter_agree: boolean;
require__session_agree: boolean; require__session_agree: boolean;
limit__navigation: boolean; limit__navigation: boolean;
limit__options: boolean;
file_purpose_option_kv: Record< file_purpose_option_kv: Record<
string, string,
{ name: string; disabled?: boolean; hidden?: boolean } { name: string; disabled?: boolean; hidden?: boolean }
@@ -336,7 +339,6 @@ export const pres_mgmt_loc_defaults: PresMgmtLocState = {
hide__locations_msg: false, hide__locations_msg: false,
hide__session_li_location_field: false, hide__session_li_location_field: false,
show__session_li_poc_field: false, show__session_li_poc_field: false,
hide__launcher_link_legacy: true,
hide__launcher_link: true, hide__launcher_link: true,
hide__location_link: true, hide__location_link: true,
show__direct_download: false, show__direct_download: false,
@@ -378,10 +380,11 @@ export const pres_mgmt_loc_defaults: PresMgmtLocState = {
show__copy_access_link: false, show__copy_access_link: false,
show__email_access_link: false, show__email_access_link: false,
show__launcher_link: false, show__launcher_link: false,
show__session_qr: false,
show__presenter_qr: false,
require__presenter_agree: false, require__presenter_agree: false,
require__session_agree: false, require__session_agree: false,
limit__navigation: false, limit__navigation: false,
limit__options: false,
file_purpose_option_kv: null, file_purpose_option_kv: null,
hide__report_kv: {} hide__report_kv: {}
}; };

View File

@@ -33,7 +33,7 @@
export const AE_LOC_VERSION = 2; // Bumped 2026-03-30: force-clear stale site_cfg_json (novi_idaa_api_key missing bug) export const AE_LOC_VERSION = 2; // Bumped 2026-03-30: force-clear stale site_cfg_json (novi_idaa_api_key missing bug)
export const AE_EVENTS_LOC_VERSION = 1; export const AE_EVENTS_LOC_VERSION = 1;
export const AE_IDAA_LOC_VERSION = 2; // Bumped 2026-05-18: change default qry__limit from 150 to 100 export const AE_IDAA_LOC_VERSION = 2; // Bumped 2026-05-18: change default qry__limit from 150 to 100
export const AE_PRES_MGMT_LOC_VERSION = 1; // Added 2026-04-02: new standalone PersistedState store export const AE_PRES_MGMT_LOC_VERSION = 2; // Bumped 2026-06-16: added show__session_qr / show__presenter_qr; removed limit__options + hide__launcher_link_legacy (Flask launcher retired)
export const AE_BADGES_LOC_VERSION = 1; // Added 2026-04-02: promoted from events_loc.badges export const AE_BADGES_LOC_VERSION = 1; // Added 2026-04-02: promoted from events_loc.badges
export const AE_LEADS_LOC_VERSION = 1; // Added 2026-04-03: promoted from events_loc.leads export const AE_LEADS_LOC_VERSION = 1; // Added 2026-04-03: promoted from events_loc.leads

View File

@@ -214,7 +214,10 @@ async function on_delete(method: 'delete' | 'disable') {
</span> </span>
</button> </button>
<!-- <button <!-- Launcher link toggle — only visible when admin has enabled launcher
(show__launcher_link) OR user has trusted_access (staff override) -->
{#if pres_mgmt_loc.current.show__launcher_link || $ae_loc.trusted_access}
<button
type="button" type="button"
onclick={() => { onclick={() => {
pres_mgmt_loc.current.hide__launcher_link = pres_mgmt_loc.current.hide__launcher_link =
@@ -232,27 +235,8 @@ async function on_delete(method: 'delete' | 'disable') {
? 'Show Launcher Links' ? 'Show Launcher Links'
: 'Hide Launcher Links?'} : 'Hide Launcher Links?'}
</span> </span>
</button> --> </button>
{/if}
<!-- <button
type="button"
onclick={() => {
pres_mgmt_loc.current.hide__launcher_link_legacy =
!pres_mgmt_loc.current.hide__launcher_link_legacy;
}}
class="btn btn-sm ae_btn_surface w-full justify-between">
{#if pres_mgmt_loc.current.hide__launcher_link_legacy}<ToggleLeft
size="1em"
class="mr-1" />{:else}<ToggleRight
size="1em"
class="mr-1" />{/if}
<span class="grow">
<Send size="1em" class="mr-1" />
{pres_mgmt_loc.current.hide__launcher_link_legacy
? 'Show Legacy Launcher Links'
: 'Hide Legacy Launcher Links?'}
</span>
</button> -->
<button <button
type="button" type="button"

View File

@@ -15,7 +15,6 @@ import {
MapPin, MapPin,
Pencil, Pencil,
Plane, Plane,
Send,
Settings, Settings,
ToggleLeft, ToggleLeft,
ToggleRight, ToggleRight,
@@ -68,7 +67,8 @@ async function on_delete(method: 'delete' | 'disable') {
event_id={$lq__event_obj?.event_id} event_id={$lq__event_obj?.event_id}
ae_core={$ae_loc.edit_mode && $ae_loc.manager_access} ae_core={$ae_loc.edit_mode && $ae_loc.manager_access}
events__locations={$ae_loc.trusted_access} events__locations={$ae_loc.trusted_access}
events__session_search={$events_slct.event_id} /> events__session_search={$events_slct.event_id &&
(!pres_mgmt_loc.current.limit__navigation || $ae_loc.trusted_access)} />
<span <span
class="ae_menu__object_options flex flex-row flex-wrap items-center justify-around gap-0.5"> class="ae_menu__object_options flex flex-row flex-wrap items-center justify-around gap-0.5">
@@ -129,6 +129,7 @@ async function on_delete(method: 'delete' | 'disable') {
Display Links Display Links
</h4> </h4>
<div class="flex flex-col gap-1"> <div class="flex flex-col gap-1">
{#if pres_mgmt_loc.current.show__launcher_link || $ae_loc.trusted_access}
<button <button
type="button" type="button"
onclick={() => { onclick={() => {
@@ -148,26 +149,7 @@ async function on_delete(method: 'delete' | 'disable') {
: 'Hide Launcher Links?'} : 'Hide Launcher Links?'}
</span> </span>
</button> </button>
{/if}
<button
type="button"
onclick={() => {
pres_mgmt_loc.current.hide__launcher_link_legacy =
!pres_mgmt_loc.current.hide__launcher_link_legacy;
}}
class="btn btn-sm ae_btn_surface w-full justify-between text-center">
{#if pres_mgmt_loc.current.hide__launcher_link_legacy}<ToggleLeft
size="1em"
class="m-1" />{:else}<ToggleRight
size="1em"
class="m-1" />{/if}
<span class="grow">
<Send size="1em" class="m-1" />
{pres_mgmt_loc.current.hide__launcher_link_legacy
? 'Show Legacy Launcher Links'
: 'Hide Legacy Launcher Links?'}
</span>
</button>
<button <button
type="button" type="button"

View File

@@ -2,14 +2,12 @@
interface Props { interface Props {
log_lvl?: number; log_lvl?: number;
hide__launcher_link?: boolean; hide__launcher_link?: boolean;
hide__launcher_link_legacy?: boolean;
lq__event_location_obj: any; lq__event_location_obj: any;
} }
let { let {
log_lvl = 0, log_lvl = 0,
hide__launcher_link = false, hide__launcher_link = false,
hide__launcher_link_legacy = true,
lq__event_location_obj lq__event_location_obj
}: Props = $props(); }: Props = $props();
@@ -45,7 +43,7 @@ import {
} from '$lib/stores/ae_events_stores'; } from '$lib/stores/ae_events_stores';
import { pres_mgmt_loc } from '$lib/stores/ae_events_stores__pres_mgmt.svelte'; import { pres_mgmt_loc } from '$lib/stores/ae_events_stores__pres_mgmt.svelte';
import { events_func } from '$lib/ae_events/ae_events_functions'; import { events_func } from '$lib/ae_events/ae_events_functions';
import { Barcode, Eye, EyeOff, Key, Plane, Send } from '@lucide/svelte'; import { Barcode, Eye, EyeOff, Key, Plane } from '@lucide/svelte';
// Exports // Exports
// export let event_location_id: string; // export let event_location_id: string;
// export let event_location_obj: key_val; // export let event_location_obj: key_val;
@@ -221,20 +219,6 @@ $effect(() => {
</Element_ae_obj_field_editor> </Element_ae_obj_field_editor>
{/if} {/if}
<!-- BEGIN: Legacy link -->
<a
data-sveltekit-preload-data="false"
href="/event/{$lq__event_location_obj?.event_id}/launcher/{$lq__event_location_obj?.event_location_id}"
class:hidden={hide__launcher_link_legacy}
class="btn btn-sm preset-tonal-secondary hover:preset-filled-secondary-500"
title="Launcher: {$lq__event_location_obj?.name} {$lq__event_location_obj?.event_location_id}">
<Send size="1em" class="m-1" />
{@html $lq__event_location_obj?.name
? $lq__event_location_obj?.name
: ae_snip.html__not_set}
</a>
<!-- END: Legacy link -->
<a <a
data-sveltekit-preload-data="false" data-sveltekit-preload-data="false"
href="/events/{$lq__event_location_obj?.event_id}/launcher/{$lq__event_location_obj?.event_location_id}" href="/events/{$lq__event_location_obj?.event_id}/launcher/{$lq__event_location_obj?.event_location_id}"

View File

@@ -487,7 +487,6 @@ if (
hide__session_location={pres_mgmt_loc.current.hide__session_li_location_field} hide__session_location={pres_mgmt_loc.current.hide__session_li_location_field}
hide__session_poc={pres_mgmt_loc.current.hide__session_poc || hide__session_poc={pres_mgmt_loc.current.hide__session_poc ||
!pres_mgmt_loc.current.show__session_li_poc_field} !pres_mgmt_loc.current.show__session_li_poc_field}
hide__launcher_link_legacy={pres_mgmt_loc.current.hide__launcher_link_legacy}
hide__launcher_link={pres_mgmt_loc.current.hide__launcher_link} hide__launcher_link={pres_mgmt_loc.current.hide__launcher_link}
hide__location_link={pres_mgmt_loc.current.hide__location_link} hide__location_link={pres_mgmt_loc.current.hide__location_link}
log_lvl={1} /> log_lvl={1} />

View File

@@ -71,10 +71,11 @@ const cfg_defaults: PressMgmtRemoteCfg = {
show__email_access_link: false, show__email_access_link: false,
show__launcher_link: false, show__launcher_link: false,
show__session_li_poc_field: false, show__session_li_poc_field: false,
show__session_qr: false,
show__presenter_qr: false,
require__presenter_agree: false, require__presenter_agree: false,
require__session_agree: false, require__session_agree: false,
limit__navigation: false, limit__navigation: false,
limit__options: false,
file_purpose_option_kv: null, file_purpose_option_kv: null,
hide__report_kv: {} hide__report_kv: {}
}; };
@@ -99,12 +100,10 @@ $effect(() => {
let is_dirty = $derived(draft_initialized && JSON.stringify(draft) !== initial_json); let is_dirty = $derived(draft_initialized && JSON.stringify(draft) !== initial_json);
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// JSON fields (file_purpose_option_kv, hide__report_kv) as textarea strings // JSON fields (file_purpose_option_kv) as textarea string
// --------------------------------------------------------------------------- // hide__report_kv is edited via structured per-slug toggles (no JSON textarea needed)
let file_purpose_json_str = $state(''); let file_purpose_json_str = $state('');
let file_purpose_json_error = $state(''); let file_purpose_json_error = $state('');
let report_kv_json_str = $state('');
let report_kv_json_error = $state('');
$effect(() => { $effect(() => {
if (draft_initialized) { if (draft_initialized) {
@@ -112,10 +111,6 @@ $effect(() => {
file_purpose_json_str = draft.file_purpose_option_kv file_purpose_json_str = draft.file_purpose_option_kv
? JSON.stringify(draft.file_purpose_option_kv, null, 2) ? JSON.stringify(draft.file_purpose_option_kv, null, 2)
: ''; : '';
report_kv_json_str =
draft.hide__report_kv && Object.keys(draft.hide__report_kv).length
? JSON.stringify(draft.hide__report_kv, null, 2)
: '';
}); });
} }
}); });
@@ -133,19 +128,6 @@ function parse_file_purpose_json() {
} }
} }
function parse_report_kv_json() {
report_kv_json_error = '';
if (!report_kv_json_str.trim()) {
draft.hide__report_kv = {};
return;
}
try {
draft.hide__report_kv = JSON.parse(report_kv_json_str);
} catch (e) {
report_kv_json_error = 'Invalid JSON';
}
}
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Save // Save
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@@ -154,8 +136,7 @@ let save_status: 'idle' | 'saving' | 'success' | 'error' = $state('idle');
async function save() { async function save() {
if (!event_id) return; if (!event_id) return;
parse_file_purpose_json(); parse_file_purpose_json();
parse_report_kv_json(); if (file_purpose_json_error) return;
if (file_purpose_json_error || report_kv_json_error) return;
save_status = 'saving'; save_status = 'saving';
try { try {
@@ -459,7 +440,9 @@ function toggle(key: string) {
{#each [ {#each [
{ field: 'show__copy_access_link' as const, label: 'Copy Access Link' }, { field: 'show__copy_access_link' as const, label: 'Copy Access Link' },
{ field: 'show__email_access_link' as const, label: 'Email Access Link' }, { field: 'show__email_access_link' as const, label: 'Email Access Link' },
{ field: 'show__launcher_link' as const, label: 'Launcher Link' } { field: 'show__launcher_link' as const, label: 'Launcher Link' },
{ field: 'show__session_qr' as const, label: 'Session QR Code' },
{ field: 'show__presenter_qr' as const, label: 'Presenter QR Code' }
] as item (item.field)} ] as item (item.field)}
<label class="flex items-center gap-2"> <label class="flex items-center gap-2">
<input type="checkbox" class="checkbox" bind:checked={draft[item.field]} /> <input type="checkbox" class="checkbox" bind:checked={draft[item.field]} />
@@ -507,14 +490,11 @@ function toggle(key: string) {
{#if sections.navigation}<ChevronUp size="1em" />{:else}<ChevronDown size="1em" />{/if} {#if sections.navigation}<ChevronUp size="1em" />{:else}<ChevronDown size="1em" />{/if}
</button> </button>
{#if sections.navigation} {#if sections.navigation}
<div class="border-surface-200-800 grid grid-cols-2 gap-3 border-t px-4 py-3"> <div class="border-surface-200-800 grid grid-cols-1 gap-3 border-t px-4 py-3">
<p class="text-surface-500 text-xs">Hides the Session Search link for non-staff users, keeping presenters within their assigned session.</p>
<label class="flex items-center gap-2"> <label class="flex items-center gap-2">
<input type="checkbox" class="checkbox" bind:checked={draft.limit__navigation} /> <input type="checkbox" class="checkbox" bind:checked={draft.limit__navigation} />
<span class="text-sm">Limit Navigation</span> <span class="text-sm">Limit Navigation (hide Session Search for non-staff)</span>
</label>
<label class="flex items-center gap-2">
<input type="checkbox" class="checkbox" bind:checked={draft.limit__options} />
<span class="text-sm">Limit Options</span>
</label> </label>
</div> </div>
{/if} {/if}
@@ -564,20 +544,33 @@ function toggle(key: string) {
</button> </button>
{#if sections.reports} {#if sections.reports}
<div class="border-surface-200-800 space-y-2 border-t px-4 py-3"> <div class="border-surface-200-800 space-y-2 border-t px-4 py-3">
<div class="flex items-start gap-1 text-xs opacity-60"> <p class="text-surface-500 text-xs">Hidden reports are not shown to staff unless in edit mode.</p>
<Info size="1em" class="mt-0.5 flex-none" /> {#each [
JSON object: key = report slug, value = <code>true</code> to hide that report section. { slug: 'session_no_files', label: 'Sessions without Files' },
e.g. <code>&#123; "session_no_bio": true &#125;</code> { slug: 'sessions_poc_agree', label: 'Session POC Agreement' },
</div> { slug: 'session_no_bio', label: 'Session POC Bios' },
<textarea { slug: 'presenters_agree', label: 'Presenter Agreement' },
class="input font-mono text-xs" { slug: 'presenters_biography', label: 'Presenter Bios' },
rows={5} { slug: 'presenters_overview', label: 'Presenter Overview' },
placeholder='&#123; "session_no_bio": true &#125;' { slug: 'event_files', label: 'Event Files' },
bind:value={report_kv_json_str} { slug: 'file_downloads', label: 'File Downloads' }
onblur={parse_report_kv_json}></textarea> ] as rpt (rpt.slug)}
{#if report_kv_json_error} <label class="flex items-center gap-2">
<p class="text-error-500 text-xs">{report_kv_json_error}</p> <input
{/if} type="checkbox"
class="checkbox"
checked={draft.hide__report_kv[rpt.slug] ?? false}
onchange={(e) => {
if (e.currentTarget.checked) {
draft.hide__report_kv[rpt.slug] = true;
} else {
delete draft.hide__report_kv[rpt.slug];
draft.hide__report_kv = { ...draft.hide__report_kv };
}
}} />
<span class="text-sm">Hide: {rpt.label}</span>
</label>
{/each}
</div> </div>
{/if} {/if}
</section> </section>

View File

@@ -75,7 +75,8 @@ async function on_delete(method: 'delete' | 'disable') {
$ae_loc.trusted_access} $ae_loc.trusted_access}
events__session_id={$lq__event_presenter_obj?.event_session_id} events__session_id={$lq__event_presenter_obj?.event_session_id}
events__launcher_session_id={$lq__event_presenter_obj?.event_session_id} events__launcher_session_id={$lq__event_presenter_obj?.event_session_id}
events__session_search={$events_slct.event_id} /> events__session_search={$events_slct.event_id &&
(!pres_mgmt_loc.current.limit__navigation || $ae_loc.trusted_access)} />
<div <div
class="flex w-full flex-row flex-wrap items-center justify-between gap-1"> class="flex w-full flex-row flex-wrap items-center justify-between gap-1">
@@ -181,6 +182,7 @@ async function on_delete(method: 'delete' | 'disable') {
Display Display
</h4> </h4>
<div class="flex flex-row flex-wrap gap-2"> <div class="flex flex-row flex-wrap gap-2">
{#if pres_mgmt_loc.current.show__presenter_qr || $ae_loc.trusted_access}
<button <button
type="button" type="button"
onclick={() => { onclick={() => {
@@ -195,6 +197,7 @@ async function on_delete(method: 'delete' | 'disable') {
? 'Hide QR Code' ? 'Hide QR Code'
: 'Show QR Code'} : 'Show QR Code'}
</button> </button>
{/if}
</div> </div>
</section> </section>
{/if} {/if}

View File

@@ -167,6 +167,7 @@ $effect(() => {
pres_mgmt_loc.current.show_report = 'session_no_files'; pres_mgmt_loc.current.show_report = 'session_no_files';
}} }}
class="btn btn-sm preset-tonal-success border-success-500 hover:preset-filled-success-500 m-1 border transition-all" class="btn btn-sm preset-tonal-success border-success-500 hover:preset-filled-success-500 m-1 border transition-all"
class:hidden={pres_mgmt_loc.current.hide__report_kv['session_no_files'] && !$ae_loc.edit_mode}
title="Toggle to show sessions with and without files uploaded."> title="Toggle to show sessions with and without files uploaded.">
{#if pres_mgmt_loc.current.show_report == 'session_no_files' && $events_sess.pres_mgmt?.status_qry__search == 'loading'} {#if pres_mgmt_loc.current.show_report == 'session_no_files' && $events_sess.pres_mgmt?.status_qry__search == 'loading'}
<LoaderCircle size="1em" class="animate-spin" /> <LoaderCircle size="1em" class="animate-spin" />
@@ -216,8 +217,7 @@ $effect(() => {
ae_triggers.rpt__event_sessions = true; ae_triggers.rpt__event_sessions = true;
pres_mgmt_loc.current.show_report = 'session_no_bio'; pres_mgmt_loc.current.show_report = 'session_no_bio';
}} }}
class:hidden={$lq__event_obj?.mod_pres_mgmt_json class:hidden={(pres_mgmt_loc.current.hide__report_kv['session_no_bio'] && !$ae_loc.edit_mode)}
?.hide__report_kv.session_no_bio && !$ae_loc.edit_mode}
class="btn btn-sm preset-tonal-success border-success-500 hover:preset-filled-success-500 m-1 border transition-all" class="btn btn-sm preset-tonal-success border-success-500 hover:preset-filled-success-500 m-1 border transition-all"
title="Show sessions without POC bios."> title="Show sessions without POC bios.">
{#if pres_mgmt_loc.current.show_report == 'session_no_bio' && $events_sess.pres_mgmt?.status_qry__search == 'loading'} {#if pres_mgmt_loc.current.show_report == 'session_no_bio' && $events_sess.pres_mgmt?.status_qry__search == 'loading'}
@@ -263,8 +263,7 @@ $effect(() => {
ae_triggers.rpt__event_presenters = true; ae_triggers.rpt__event_presenters = true;
pres_mgmt_loc.current.show_report = 'presenters_biography'; pres_mgmt_loc.current.show_report = 'presenters_biography';
}} }}
class:hidden={$lq__event_obj?.mod_pres_mgmt_json class:hidden={(pres_mgmt_loc.current.hide__report_kv['presenters_biography'] && !$ae_loc.edit_mode)}
?.hide__report_kv.presenter_no_bio && !$ae_loc.edit_mode}
class="btn btn-sm preset-tonal-success border-success-500 hover:preset-filled-success-500 m-1 border transition-all" class="btn btn-sm preset-tonal-success border-success-500 hover:preset-filled-success-500 m-1 border transition-all"
title="Show presenters with bios."> title="Show presenters with bios.">
{#if pres_mgmt_loc.current.show_report == 'presenters_biography' && $events_sess.pres_mgmt?.status_qry__search == 'loading'} {#if pres_mgmt_loc.current.show_report == 'presenters_biography' && $events_sess.pres_mgmt?.status_qry__search == 'loading'}
@@ -283,8 +282,7 @@ $effect(() => {
ae_triggers.rpt__event_presenters = true; ae_triggers.rpt__event_presenters = true;
pres_mgmt_loc.current.show_report = 'presenters_overview'; pres_mgmt_loc.current.show_report = 'presenters_overview';
}} }}
class:hidden={$lq__event_obj?.mod_pres_mgmt_json class:hidden={(pres_mgmt_loc.current.hide__report_kv['presenters_overview'] && !$ae_loc.edit_mode)}
?.hide__report_kv.presenter_overview}
class="btn btn-sm preset-tonal-success border-success-500 hover:preset-filled-success-500 m-1 border transition-all" class="btn btn-sm preset-tonal-success border-success-500 hover:preset-filled-success-500 m-1 border transition-all"
title="Show overview of presenters' statuses. (A work in progress for LCI)"> title="Show overview of presenters' statuses. (A work in progress for LCI)">
{#if pres_mgmt_loc.current.show_report == 'presenters_overview' && $events_sess.pres_mgmt?.status_qry__search == 'loading'} {#if pres_mgmt_loc.current.show_report == 'presenters_overview' && $events_sess.pres_mgmt?.status_qry__search == 'loading'}
@@ -304,8 +302,7 @@ $effect(() => {
ae_triggers.rpt__event_files = true; ae_triggers.rpt__event_files = true;
pres_mgmt_loc.current.show_report = 'event_files'; pres_mgmt_loc.current.show_report = 'event_files';
}} }}
class:hidden={$lq__event_obj?.mod_pres_mgmt_json class:hidden={(pres_mgmt_loc.current.hide__report_kv['event_files'] && !$ae_loc.edit_mode)}
?.hide__report_kv.event_files}
class="btn btn-sm preset-tonal-success border-success-500 hover:preset-filled-success-500 m-1 border transition-all" class="btn btn-sm preset-tonal-success border-success-500 hover:preset-filled-success-500 m-1 border transition-all"
title="Show large file uploads."> title="Show large file uploads.">
{#if $events_sess.pres_mgmt?.show_report == 'event_files' && $events_sess.pres_mgmt.status_rpt[$events_sess.pres_mgmt?.show_report] == 'loading'} {#if $events_sess.pres_mgmt?.show_report == 'event_files' && $events_sess.pres_mgmt.status_rpt[$events_sess.pres_mgmt?.show_report] == 'loading'}
@@ -322,8 +319,7 @@ $effect(() => {
ae_triggers.rpt__file_downloads = true; ae_triggers.rpt__file_downloads = true;
pres_mgmt_loc.current.show_report = 'file_downloads'; pres_mgmt_loc.current.show_report = 'file_downloads';
}} }}
class:hidden={$lq__event_obj?.mod_pres_mgmt_json class:hidden={(pres_mgmt_loc.current.hide__report_kv['file_downloads'] && !$ae_loc.edit_mode)}
?.hide__report_kv.file_downloads}
class="btn btn-sm preset-tonal-success border-success-500 hover:preset-filled-success-500 m-1 border transition-all" class="btn btn-sm preset-tonal-success border-success-500 hover:preset-filled-success-500 m-1 border transition-all"
title="File Downloads — download files grouped by session and presenter with clean filename options."> title="File Downloads — download files grouped by session and presenter with clean filename options.">
{#if pres_mgmt_loc.current.show_report == 'file_downloads' && $events_sess.pres_mgmt.status_rpt.file_downloads == 'loading'} {#if pres_mgmt_loc.current.show_report == 'file_downloads' && $events_sess.pres_mgmt.status_rpt.file_downloads == 'loading'}

View File

@@ -83,7 +83,8 @@ async function toggle_hide_launcher() {
event_id={$lq__event_session_obj?.event_id} event_id={$lq__event_session_obj?.event_id}
events__reports={$lq__event_session_obj?.event_id && events__reports={$lq__event_session_obj?.event_id &&
$ae_loc.trusted_access} $ae_loc.trusted_access}
events__session_search={$lq__event_session_obj?.event_id} events__session_search={$lq__event_session_obj?.event_id &&
(!pres_mgmt_loc.current.limit__navigation || $ae_loc.trusted_access)}
events__launcher_id={$lq__event_session_obj?.event_location_id && events__launcher_id={$lq__event_session_obj?.event_location_id &&
$ae_loc.administrator_access $ae_loc.administrator_access
? $lq__event_session_obj?.event_location_id ? $lq__event_session_obj?.event_location_id

View File

@@ -7,7 +7,6 @@ interface Props {
hide__session_location?: boolean; hide__session_location?: boolean;
hide__session_poc?: boolean; hide__session_poc?: boolean;
hide__admin?: boolean; hide__admin?: boolean;
hide__launcher_link_legacy?: boolean;
hide__launcher_link?: boolean; hide__launcher_link?: boolean;
hide__location_link?: boolean; hide__location_link?: boolean;
show__session_files?: boolean; show__session_files?: boolean;
@@ -22,7 +21,6 @@ let {
hide__session_location = $bindable(false), hide__session_location = $bindable(false),
hide__session_poc = $bindable(false), hide__session_poc = $bindable(false),
hide__admin = $bindable(false), hide__admin = $bindable(false),
hide__launcher_link_legacy = $bindable(false),
hide__launcher_link = $bindable(false), hide__launcher_link = $bindable(false),
hide__location_link = $bindable(false), hide__location_link = $bindable(false),
show__session_files = $bindable(false), show__session_files = $bindable(false),

View File

@@ -8,7 +8,6 @@ interface Props {
hide__session_location?: boolean; hide__session_location?: boolean;
hide__session_poc?: boolean; hide__session_poc?: boolean;
hide__admin?: boolean; hide__admin?: boolean;
hide__launcher_link_legacy?: boolean;
hide__launcher_link?: boolean; hide__launcher_link?: boolean;
hide__location_link?: boolean; hide__location_link?: boolean;
log_lvl?: number; log_lvl?: number;
@@ -23,7 +22,6 @@ let {
hide__session_location = $bindable(false), hide__session_location = $bindable(false),
hide__session_poc = $bindable(false), hide__session_poc = $bindable(false),
hide__admin = $bindable(false), hide__admin = $bindable(false),
hide__launcher_link_legacy = $bindable(false),
hide__launcher_link = $bindable(false), hide__launcher_link = $bindable(false),
hide__location_link = $bindable(false), hide__location_link = $bindable(false),
log_lvl = 0 log_lvl = 0
@@ -62,7 +60,6 @@ let lq__event_session_obj_li = $derived.by(() => {
{hide__session_location} {hide__session_location}
{hide__session_poc} {hide__session_poc}
{hide__admin} {hide__admin}
{hide__launcher_link_legacy}
{hide__launcher_link} {hide__launcher_link}
{hide__location_link} {hide__location_link}
{log_lvl}></Comp_event_session_obj_li> {log_lvl}></Comp_event_session_obj_li>

View File

@@ -76,6 +76,7 @@ import {
class:hidden={!pres_mgmt_loc.current.expand__menu_opts}> class:hidden={!pres_mgmt_loc.current.expand__menu_opts}>
{#if $ae_loc.authenticated_access} {#if $ae_loc.authenticated_access}
<div class="flex flex-col items-end justify-center gap-1"> <div class="flex flex-col items-end justify-center gap-1">
<p class="text-surface-500 w-full text-right text-xs font-semibold uppercase tracking-wide">Query Limits</p>
<span class="flex flex-col items-end justify-center gap-1"> <span class="flex flex-col items-end justify-center gap-1">
<!-- Max person select options --> <!-- Max person select options -->
<span <span
@@ -252,6 +253,7 @@ import {
{/if} {/if}
<div class="flex flex-col flex-wrap items-center justify-evenly gap-1"> <div class="flex flex-col flex-wrap items-center justify-evenly gap-1">
<p class="text-surface-500 w-full text-center text-xs font-semibold uppercase tracking-wide">Display &amp; Search</p>
<button <button
type="button" type="button"
onclick={() => { onclick={() => {
@@ -340,6 +342,7 @@ import {
</div> </div>
<div class="flex flex-col items-center justify-center gap-1"> <div class="flex flex-col items-center justify-center gap-1">
<p class="text-surface-500 w-full text-center text-xs font-semibold uppercase tracking-wide">Staff Options</p>
{#if $ae_loc.trusted_access} {#if $ae_loc.trusted_access}
<div class="flex flex-col items-center justify-center gap-1"> <div class="flex flex-col items-center justify-center gap-1">
{#if pres_mgmt_loc.current.show__copy_access_link} {#if pres_mgmt_loc.current.show__copy_access_link}
@@ -390,6 +393,7 @@ import {
{#if $ae_loc.authenticated_access} {#if $ae_loc.authenticated_access}
<div class="flex flex-col items-end justify-center gap-1"> <div class="flex flex-col items-end justify-center gap-1">
{#if pres_mgmt_loc.current.show__session_qr || $ae_loc.trusted_access}
{#if pres_mgmt_loc.current.show_content__session_qr} {#if pres_mgmt_loc.current.show_content__session_qr}
<button <button
type="button" type="button"
@@ -419,7 +423,9 @@ import {
</span> </span>
</button> </button>
{/if} {/if}
{/if}
{#if pres_mgmt_loc.current.show__presenter_qr || $ae_loc.trusted_access}
{#if pres_mgmt_loc.current.show_content__presenter_qr} {#if pres_mgmt_loc.current.show_content__presenter_qr}
<button <button
type="button" type="button"
@@ -449,13 +455,16 @@ import {
</span> </span>
</button> </button>
{/if} {/if}
{/if}
</div> </div>
{/if} {/if}
</div> </div>
{#if $ae_loc.authenticated_access} {#if $ae_loc.authenticated_access}
<div class="flex flex-col items-center justify-center gap-1"> <div class="flex flex-col items-center justify-center gap-1">
<!-- Show/Hide launcher links (new version) --> <!-- Show/Hide launcher links — only visible when admin has enabled launcher (show__launcher_link)
OR user has trusted_access (staff onsite override) -->
{#if pres_mgmt_loc.current.show__launcher_link || $ae_loc.trusted_access}
<button <button
type="button" type="button"
onclick={() => { onclick={() => {
@@ -475,27 +484,7 @@ import {
: 'Hide Launcher Links?'} : 'Hide Launcher Links?'}
</span> </span>
</button> </button>
{/if}
<!-- Show/Hide launcher links (legacy version) -->
<!-- <button
type="button"
onclick={() => {
pres_mgmt_loc.current.hide__launcher_link_legacy =
!pres_mgmt_loc.current.hide__launcher_link_legacy;
}}
class="btn btn-sm ae_btn_surface w-full justify-between text-center">
{#if pres_mgmt_loc.current.hide__launcher_link_legacy}<ToggleLeft
size="1em"
class="m-1" />{:else}<ToggleRight
size="1em"
class="m-1" />{/if}
<span class="grow">
<Send size="1em" class="m-1" />
{pres_mgmt_loc.current.hide__launcher_link_legacy
? 'Show Legacy Launcher Links'
: 'Hide Legacy Launcher Links?'}
</span>
</button> -->
<!-- Show/Hide links to the location (room) --> <!-- Show/Hide links to the location (room) -->
<button <button