pres_mgmt: migrate to typed PersistedState store, canonical config schema
Replaces untyped $events_loc.pres_mgmt (svelte-persisted-store) with a dedicated pres_mgmt_loc (runed PersistedState) backed by a fully typed PresMgmtLocState interface and PressMgmtRemoteCfg for the server-side JSON. Key changes: - ae_events_stores__pres_mgmt_defaults.ts: canonical interfaces + defaults covering all hide__/show__ fields, labels, report prefs, query filters, and lock_config sync fields; qry_enabled uses 'not_enabled' (matches API) - ae_events_stores__pres_mgmt.svelte.ts: new PersistedState store - ae_events__event.ts: sync_config__event_pres_mgmt() rewired to write directly to pres_mgmt_loc.current; launcher link inversion preserved - All 26+ pres_mgmt templates migrated from $events_loc.pres_mgmt.* to pres_mgmt_loc.current.* - New config UI at (pres_mgmt)/pres_mgmt/config/ — manager + edit mode only - Event settings page: removed embedded pres_mgmt form, links to config page - event_page_menu: Config button visible only when manager_access + edit_mode Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
import type { key_val } from '$lib/stores/ae_stores';
|
||||
import { api } from '$lib/api/api';
|
||||
import { pres_mgmt_loc } from '$lib/stores/ae_events_stores__pres_mgmt.svelte';
|
||||
import type { PressMgmtRemoteCfg } from '$lib/stores/ae_events_stores__pres_mgmt_defaults';
|
||||
|
||||
import { db_save_ae_obj_li__ae_obj } from '$lib/ae_core/core__idb_dexie';
|
||||
import { db_events } from '$lib/ae_events/db_events';
|
||||
@@ -944,83 +946,117 @@ export async function process_ae_obj__event_props({
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* sync_config__event_pres_mgmt
|
||||
*
|
||||
* Syncs the server-side event pres_mgmt config (mod_pres_mgmt_json) into the
|
||||
* local PersistedState store (pres_mgmt_loc.current).
|
||||
*
|
||||
* Called reactively in pres_mgmt/+page.svelte whenever the event object changes.
|
||||
*
|
||||
* Always-synced fields: labels, requirements, access links, file config.
|
||||
* Lock-synced fields (only when lock_config=true): all visibility/hide__ toggles,
|
||||
* launcher links, navigation limits. This prevents presenter laptops from
|
||||
* drifting into different display configs across a conference.
|
||||
*
|
||||
* Canonical key convention (enforced here):
|
||||
* hide__* → feature ON by default; true = turn off (default: false = visible)
|
||||
* show__* → feature OFF by default; true = turn on (default: false = hidden)
|
||||
*/
|
||||
export function sync_config__event_pres_mgmt({
|
||||
pres_mgmt_cfg_remote,
|
||||
pres_mgmt_cfg_local,
|
||||
log_lvl = 0
|
||||
}: {
|
||||
pres_mgmt_cfg_remote: key_val;
|
||||
pres_mgmt_cfg_local: key_val;
|
||||
pres_mgmt_cfg_remote: Partial<PressMgmtRemoteCfg>;
|
||||
log_lvl?: number;
|
||||
}) {
|
||||
if (log_lvl) {
|
||||
console.log(
|
||||
`*** sync_config__event_pres_mgmt() *** pres_mgmt_cfg_remote:`,
|
||||
`*** sync_config__event_pres_mgmt() *** remote:`,
|
||||
pres_mgmt_cfg_remote
|
||||
);
|
||||
}
|
||||
|
||||
pres_mgmt_cfg_local.label__person_external_id =
|
||||
const loc = pres_mgmt_loc.current;
|
||||
|
||||
// --- Always sync: labels, requirements, opt-in features, file config ---
|
||||
// These are safe to always apply — they don't override local display preferences.
|
||||
loc.label__person_external_id =
|
||||
pres_mgmt_cfg_remote?.label__person_external_id ?? 'External ID';
|
||||
pres_mgmt_cfg_local.label__presenter_external_id =
|
||||
loc.label__presenter_external_id =
|
||||
pres_mgmt_cfg_remote?.label__presenter_external_id ?? 'External ID';
|
||||
pres_mgmt_cfg_local.label__session_poc_type =
|
||||
loc.label__session_poc_type =
|
||||
pres_mgmt_cfg_remote?.label__session_poc_type ?? 'poc';
|
||||
pres_mgmt_cfg_local.label__session_poc_name =
|
||||
pres_mgmt_cfg_remote?.label__session_poc_name_short ?? 'POC';
|
||||
pres_mgmt_cfg_local.label__session_poc_name =
|
||||
loc.label__session_poc_name =
|
||||
pres_mgmt_cfg_remote?.label__session_poc_name ?? 'Point of Contact';
|
||||
pres_mgmt_cfg_local.hide__session_poc =
|
||||
pres_mgmt_cfg_remote?.hide__session_poc ?? false;
|
||||
pres_mgmt_cfg_local.require__presenter_agree =
|
||||
|
||||
loc.require__presenter_agree =
|
||||
pres_mgmt_cfg_remote?.require__presenter_agree ?? false;
|
||||
pres_mgmt_cfg_local.require__session_agree =
|
||||
loc.require__session_agree =
|
||||
pres_mgmt_cfg_remote?.require__session_agree ?? false;
|
||||
pres_mgmt_cfg_local.show__copy_access_link =
|
||||
|
||||
loc.show__copy_access_link =
|
||||
pres_mgmt_cfg_remote?.show__copy_access_link ?? false;
|
||||
pres_mgmt_cfg_local.show__email_access_link =
|
||||
loc.show__email_access_link =
|
||||
pres_mgmt_cfg_remote?.show__email_access_link ?? false;
|
||||
pres_mgmt_cfg_local.file_purpose_option_kv =
|
||||
|
||||
loc.file_purpose_option_kv =
|
||||
pres_mgmt_cfg_remote?.file_purpose_option_kv ?? null;
|
||||
|
||||
if (pres_mgmt_cfg_local.lock_config) {
|
||||
console.log(`The config should be locked! Forcing the sync!`);
|
||||
pres_mgmt_cfg_local.sync_local_config = true;
|
||||
}
|
||||
loc.hide__report_kv = pres_mgmt_cfg_remote?.hide__report_kv ?? {};
|
||||
|
||||
if (pres_mgmt_cfg_local?.sync_local_config) {
|
||||
pres_mgmt_cfg_local.hide__location_code =
|
||||
// --- Lock-synced: visibility, launcher, navigation, session/presenter fields ---
|
||||
// When lock_config=true the remote config wins for ALL display flags, preventing
|
||||
// local browser state from overriding the admin's event-level configuration.
|
||||
if (pres_mgmt_cfg_remote?.lock_config) {
|
||||
if (log_lvl) console.log(`sync_config__event_pres_mgmt: lock_config=true, forcing full sync`);
|
||||
|
||||
// Codes
|
||||
loc.hide__location_code =
|
||||
pres_mgmt_cfg_remote?.hide__location_code ?? false;
|
||||
pres_mgmt_cfg_local.hide__presentation_code =
|
||||
loc.hide__presentation_code =
|
||||
pres_mgmt_cfg_remote?.hide__presentation_code ?? false;
|
||||
pres_mgmt_cfg_local.hide__presentation_datetime =
|
||||
pres_mgmt_cfg_remote?.hide__presentation_datetime ?? false;
|
||||
pres_mgmt_cfg_local.show_content__presentation_description =
|
||||
pres_mgmt_cfg_remote?.show_content__presentation_description ??
|
||||
false;
|
||||
pres_mgmt_cfg_local.hide__presenter_code =
|
||||
loc.hide__presenter_code =
|
||||
pres_mgmt_cfg_remote?.hide__presenter_code ?? false;
|
||||
pres_mgmt_cfg_local.hide__presenter_biography =
|
||||
pres_mgmt_cfg_remote?.hide__presenter_biography ?? false;
|
||||
pres_mgmt_cfg_local.hide__session_code =
|
||||
loc.hide__session_code =
|
||||
pres_mgmt_cfg_remote?.hide__session_code ?? false;
|
||||
pres_mgmt_cfg_local.hide__session_description =
|
||||
pres_mgmt_cfg_remote?.hide__session_description ?? false;
|
||||
pres_mgmt_cfg_local.hide__session_location =
|
||||
pres_mgmt_cfg_remote?.hide__session_location ?? false;
|
||||
pres_mgmt_cfg_local.hide__session_msg =
|
||||
pres_mgmt_cfg_remote?.hide__session_msg ?? false;
|
||||
pres_mgmt_cfg_local.hide__session_poc_profile =
|
||||
pres_mgmt_cfg_remote?.hide__session_poc_profile ?? false;
|
||||
pres_mgmt_cfg_local.hide__session_poc_biography =
|
||||
pres_mgmt_cfg_remote?.hide__session_poc_biography ?? false;
|
||||
pres_mgmt_cfg_local.hide__session_poc_profile_pic =
|
||||
pres_mgmt_cfg_remote?.hide__session_poc_profile_pic ?? false;
|
||||
pres_mgmt_cfg_local.hide_launcher_link =
|
||||
pres_mgmt_cfg_remote?.hide_launcher_link ?? false;
|
||||
pres_mgmt_cfg_local.hide_launcher_link_legacy =
|
||||
pres_mgmt_cfg_remote?.hide_launcher_link_legacy ?? false;
|
||||
}
|
||||
|
||||
return pres_mgmt_cfg_local;
|
||||
// Session fields
|
||||
loc.hide__session_description =
|
||||
pres_mgmt_cfg_remote?.hide__session_description ?? false;
|
||||
loc.hide__session_location =
|
||||
pres_mgmt_cfg_remote?.hide__session_location ?? false;
|
||||
loc.hide__session_msg =
|
||||
pres_mgmt_cfg_remote?.hide__session_msg ?? false;
|
||||
loc.hide__session_poc =
|
||||
pres_mgmt_cfg_remote?.hide__session_poc ?? false;
|
||||
loc.hide__session_poc_biography =
|
||||
pres_mgmt_cfg_remote?.hide__session_poc_biography ?? false;
|
||||
loc.hide__session_poc_profile =
|
||||
pres_mgmt_cfg_remote?.hide__session_poc_profile ?? false;
|
||||
loc.hide__session_poc_profile_pic =
|
||||
pres_mgmt_cfg_remote?.hide__session_poc_profile_pic ?? false;
|
||||
|
||||
// Presenter fields
|
||||
loc.hide__presenter_biography =
|
||||
pres_mgmt_cfg_remote?.hide__presenter_biography ?? false;
|
||||
|
||||
// Presentation fields
|
||||
loc.hide__presentation_datetime =
|
||||
pres_mgmt_cfg_remote?.hide__presentation_datetime ?? false;
|
||||
loc.hide__presentation_description =
|
||||
pres_mgmt_cfg_remote?.hide__presentation_description ?? false;
|
||||
|
||||
// Launcher links (show__ in remote → invert to hide__ in local display state)
|
||||
loc.hide__launcher_link =
|
||||
!(pres_mgmt_cfg_remote?.show__launcher_link ?? false);
|
||||
loc.hide__launcher_link_legacy =
|
||||
!(pres_mgmt_cfg_remote?.show__launcher_link_legacy ?? false);
|
||||
|
||||
// Navigation / UI constraints
|
||||
loc.limit__navigation =
|
||||
pres_mgmt_cfg_remote?.limit__navigation ?? false;
|
||||
loc.limit__options =
|
||||
pres_mgmt_cfg_remote?.limit__options ?? false;
|
||||
}
|
||||
}
|
||||
|
||||
18
src/lib/stores/ae_events_stores__pres_mgmt.svelte.ts
Normal file
18
src/lib/stores/ae_events_stores__pres_mgmt.svelte.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* ae_events_stores__pres_mgmt.svelte.ts
|
||||
*
|
||||
* Svelte 5 PersistedState store for Presentation Management local config.
|
||||
* Replaces the `events_loc.pres_mgmt` sub-object from the Svelte 4 persisted store.
|
||||
*
|
||||
* localStorage key: 'ae_pres_mgmt_loc'
|
||||
* Version gate: AE_PRES_MGMT_LOC_VERSION in store_versions.ts
|
||||
*
|
||||
* Usage:
|
||||
* import { pres_mgmt_loc } from '$lib/stores/ae_events_stores__pres_mgmt.svelte';
|
||||
* pres_mgmt_loc.current.hide__session_code // read
|
||||
* pres_mgmt_loc.current.hide__session_code = true // write
|
||||
*/
|
||||
import { PersistedState } from 'runed';
|
||||
import { pres_mgmt_loc_defaults } from './ae_events_stores__pres_mgmt_defaults';
|
||||
|
||||
export const pres_mgmt_loc = new PersistedState('ae_pres_mgmt_loc', pres_mgmt_loc_defaults);
|
||||
@@ -1,19 +1,95 @@
|
||||
/**
|
||||
* ae_events_stores__pres_mgmt_defaults.ts
|
||||
*
|
||||
* Default state for the pres_mgmt (Presentation Management) section of ae_events_stores.ts.
|
||||
* pres_mgmt_loc_defaults → events_loc.pres_mgmt (persisted to localStorage)
|
||||
* pres_mgmt_sess_defaults → events_sess.pres_mgmt (in-memory, resets on page load)
|
||||
* Type definitions and defaults for the Pres Mgmt stores.
|
||||
*
|
||||
* PressMgmtRemoteCfg → shape of event.mod_pres_mgmt_json (server-side admin config)
|
||||
* PresMgmtLocState → pres_mgmt_loc (PersistedState, localStorage)
|
||||
* PresMgmtSessState → events_sess.pres_mgmt (in-memory, resets on page load)
|
||||
*
|
||||
* NAMING CONVENTION (enforced here, must not mix):
|
||||
* hide__* → feature is ON by default; true = turn it off (default: false = visible)
|
||||
* show__* → feature is OFF by default; true = turn it on (default: false = hidden)
|
||||
* Never use both hide__foo and show__foo for the same concept.
|
||||
*/
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Remote config — shape of event.mod_pres_mgmt_json
|
||||
// This is the admin-controlled, server-side config for an event.
|
||||
// lock_config: true forces every field below to sync into local state on load.
|
||||
// ---------------------------------------------------------------------------
|
||||
export interface PressMgmtRemoteCfg {
|
||||
// System
|
||||
lock_config: boolean; // true = force all fields below into local state
|
||||
|
||||
// Labels — event-specific terminology overrides
|
||||
label__person_external_id: string | null; // default: 'External ID'
|
||||
label__presenter_external_id: string | null; // default: 'External ID'
|
||||
label__session_poc_type: string | null; // e.g. 'champion', 'poc'
|
||||
label__session_poc_name: string | null; // e.g. 'Champion', 'Point of Contact'
|
||||
|
||||
// Code visibility (visible by default)
|
||||
hide__location_code: boolean;
|
||||
hide__presentation_code: boolean;
|
||||
hide__presenter_code: boolean;
|
||||
hide__session_code: boolean;
|
||||
|
||||
// Session field visibility (visible by default)
|
||||
hide__session_description: boolean;
|
||||
hide__session_location: boolean;
|
||||
hide__session_msg: boolean;
|
||||
hide__session_poc: boolean;
|
||||
hide__session_poc_biography: boolean;
|
||||
hide__session_poc_profile: boolean;
|
||||
hide__session_poc_profile_pic: boolean;
|
||||
|
||||
// Presenter field visibility
|
||||
hide__presenter_biography: boolean;
|
||||
|
||||
// Presentation field visibility
|
||||
hide__presentation_datetime: boolean;
|
||||
hide__presentation_description: boolean; // replaces show_content__presentation_description
|
||||
|
||||
// Opt-in features (hidden by default — set true to enable)
|
||||
show__copy_access_link: boolean;
|
||||
show__email_access_link: boolean;
|
||||
show__launcher_link: boolean;
|
||||
show__launcher_link_legacy: boolean;
|
||||
|
||||
// Requirements
|
||||
require__presenter_agree: boolean;
|
||||
require__session_agree: boolean;
|
||||
|
||||
// Navigation / UI constraints
|
||||
limit__navigation: boolean;
|
||||
limit__options: boolean;
|
||||
|
||||
// File upload options (null = use system default)
|
||||
file_purpose_option_kv: Record<
|
||||
string,
|
||||
{ name: string; disabled?: boolean; hidden?: boolean }
|
||||
> | null;
|
||||
|
||||
// Report section visibility (key = report slug, true = hide that report)
|
||||
hide__report_kv: Record<string, boolean>;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Local state — persisted to localStorage via PersistedState ('ae_pres_mgmt_loc')
|
||||
// Contains both user preferences AND fields synced from PressMgmtRemoteCfg.
|
||||
// Fields synced from remote are overwritten on every event load when lock_config=true.
|
||||
// ---------------------------------------------------------------------------
|
||||
export interface PresMgmtLocState {
|
||||
// --- System / lock state (mirrored from remote for display) ---
|
||||
sync_local_config: boolean;
|
||||
lock_config: boolean;
|
||||
|
||||
// --- Query / search preferences ---
|
||||
datetime_format: string;
|
||||
time_format: string;
|
||||
time_hours: 12 | 24;
|
||||
qry_enabled: string; // 'all' | 'disabled' | 'enabled'
|
||||
qry_hidden: string; // 'all' | 'hidden' | 'not_hidden'
|
||||
qry_enabled: 'all' | 'not_enabled' | 'enabled';
|
||||
qry_hidden: 'all' | 'hidden' | 'not_hidden';
|
||||
qry_limit__files: number;
|
||||
qry_limit__presentations: number;
|
||||
qry_limit__presenters: number;
|
||||
@@ -26,11 +102,29 @@ export interface PresMgmtLocState {
|
||||
qry_and__file_count: boolean;
|
||||
save_search_text: boolean;
|
||||
saved_search__session: string | null;
|
||||
require__presenter_agree: boolean;
|
||||
require__session_agree: boolean;
|
||||
saved_search__session_location_name: string | null;
|
||||
fulltext_search_qry_str: string | null; // persisted search text (when save_search_text=true)
|
||||
location_name_qry_str: string | null; // persisted location filter text
|
||||
refresh_interval: number; // auto-refresh interval in seconds (0 = disabled)
|
||||
|
||||
// --- Report display preferences (user-controlled, persisted) ---
|
||||
rpt__session_no_files: boolean; // show "sessions with no files" report section
|
||||
rpt__session_poc_agree: boolean; // show "session POC agreement" report section
|
||||
rpt__session_no_bio: boolean; // show "sessions with no bio" report section
|
||||
rpt__presenter_agree: boolean; // show "presenter agreement" report section
|
||||
qry__file_purpose: string | null; // filter report files by purpose slug
|
||||
qry__files_min_size: number | null; // filter report files by minimum size (bytes)
|
||||
qry__session_sort: string; // sort order for session report
|
||||
qry__presenter_sort: string; // sort order for presenter report
|
||||
|
||||
// --- Content / panel visibility (user preferences) ---
|
||||
expand__menu_opts: boolean;
|
||||
show_content__device_description: boolean;
|
||||
show_content__event_view: string | null;
|
||||
show_content__location_description: boolean;
|
||||
show_content__location_devices_sessions: 'sessions' | 'devices' | null;
|
||||
show_content__location_qr: boolean;
|
||||
show_content__presentation_description: boolean;
|
||||
show_content__presentation_description: boolean; // per-presentation expand toggle
|
||||
show_content__presenter_page_help: boolean;
|
||||
show_content__presenter_view: string | null;
|
||||
show_content__presenter_qr: boolean;
|
||||
@@ -43,34 +137,77 @@ export interface PresMgmtLocState {
|
||||
show_content__session_search_room_name: boolean;
|
||||
show_content__session_view: string | null;
|
||||
show_content__session_qr: boolean;
|
||||
hide__session_code: boolean;
|
||||
hide__session_msg: boolean;
|
||||
hide__session_poc: boolean;
|
||||
hide__session_poc_biography: boolean;
|
||||
hide__presenter_biography: boolean;
|
||||
hide__session_li_location_field: boolean;
|
||||
show__session_li_poc_field: boolean;
|
||||
hide__launcher_link_legacy: boolean;
|
||||
hide__launcher_link: boolean;
|
||||
hide__location_link: boolean;
|
||||
show_content__disabled_files: boolean;
|
||||
show_content__hidden_files: boolean;
|
||||
show_content__hidden_presentations: boolean;
|
||||
show_content__hidden_presenters: boolean;
|
||||
show_content__hidden_sessions: boolean;
|
||||
|
||||
// --- List/table column visibility (user preferences) ---
|
||||
hide__device_code: boolean;
|
||||
hide__locations_msg: boolean;
|
||||
hide__session_li_location_field: boolean;
|
||||
show__session_li_poc_field: boolean;
|
||||
// Launcher/location links in session list
|
||||
hide__launcher_link_legacy: boolean; // Flask/legacy launcher
|
||||
hide__launcher_link: boolean; // SvelteKit launcher
|
||||
hide__location_link: boolean;
|
||||
show__direct_download: boolean;
|
||||
// null = use server-side default.
|
||||
|
||||
// --- Menu visibility (null = use server-side default) ---
|
||||
show_menu__presenter: boolean | null;
|
||||
show_menu__session: boolean | null;
|
||||
show_menu__session_search: boolean | null;
|
||||
show_menu__event_reports: boolean | null;
|
||||
show_report: string | null;
|
||||
|
||||
// --- Opt-out toggles ---
|
||||
disable_submit__opt_out: boolean;
|
||||
submit_status__opt_out: string | null;
|
||||
|
||||
// --- Device/location scratch space ---
|
||||
device_kv: Record<string, any>;
|
||||
location_kv: Record<string, any>;
|
||||
|
||||
// --- Synced from PressMgmtRemoteCfg (overwritten by sync_config__event_pres_mgmt) ---
|
||||
// These mirror PressMgmtRemoteCfg fields and are written during event load.
|
||||
// Do not set these manually — they will be overridden when lock_config=true.
|
||||
label__person_external_id: string;
|
||||
label__presenter_external_id: string;
|
||||
label__session_poc_type: string;
|
||||
label__session_poc_name: string;
|
||||
hide__location_code: boolean;
|
||||
hide__presentation_code: boolean;
|
||||
hide__presentation_datetime: boolean;
|
||||
hide__presentation_description: boolean;
|
||||
hide__presenter_code: boolean;
|
||||
hide__presenter_biography: boolean;
|
||||
hide__session_code: boolean;
|
||||
hide__session_description: boolean;
|
||||
hide__session_location: boolean;
|
||||
hide__session_msg: boolean;
|
||||
hide__session_poc: boolean;
|
||||
hide__session_poc_biography: boolean;
|
||||
hide__session_poc_profile: boolean;
|
||||
hide__session_poc_profile_pic: boolean;
|
||||
show__copy_access_link: boolean;
|
||||
show__email_access_link: boolean;
|
||||
show__launcher_link: boolean;
|
||||
show__launcher_link_legacy: boolean;
|
||||
require__presenter_agree: boolean;
|
||||
require__session_agree: boolean;
|
||||
limit__navigation: boolean;
|
||||
limit__options: boolean;
|
||||
file_purpose_option_kv: Record<
|
||||
string,
|
||||
{ name: string; disabled?: boolean; hidden?: boolean }
|
||||
> | null;
|
||||
hide__report_kv: Record<string, boolean>;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// In-memory session state — resets on page load (not persisted)
|
||||
// ---------------------------------------------------------------------------
|
||||
export interface PresMgmtSessState {
|
||||
presenter__updated_on: string | null;
|
||||
session_updated_on: string | null;
|
||||
@@ -114,40 +251,57 @@ export interface PresMgmtSessState {
|
||||
tmp_val__filename_no_ext: string | null;
|
||||
}
|
||||
|
||||
// Persisted pres_mgmt config — survives browser sessions.
|
||||
export const pres_mgmt_loc_defaults: PresMgmtLocState = {
|
||||
sync_local_config: false,
|
||||
lock_config: true,
|
||||
// ---------------------------------------------------------------------------
|
||||
// Defaults
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
// Persisted pres_mgmt local config — survives browser sessions.
|
||||
export const pres_mgmt_loc_defaults: PresMgmtLocState = {
|
||||
// System / lock state
|
||||
sync_local_config: false,
|
||||
lock_config: false,
|
||||
|
||||
// Query / search
|
||||
datetime_format: 'datetime_12_long',
|
||||
time_format: 'time_12_short',
|
||||
time_hours: 12, // 12 or 24
|
||||
|
||||
qry_enabled: 'enabled', // 'all' | 'disabled' | 'enabled'
|
||||
qry_hidden: 'not_hidden', // 'all' | 'hidden' | 'not_hidden'
|
||||
time_hours: 12,
|
||||
qry_enabled: 'enabled',
|
||||
qry_hidden: 'not_hidden',
|
||||
qry_limit__files: 75,
|
||||
qry_limit__presentations: 25,
|
||||
qry_limit__presenters: 500,
|
||||
qry_limit__sessions: 100,
|
||||
qry_max: 500, // Maximum value the limit is allowed to be set to.
|
||||
qry_max: 500,
|
||||
qry__files_offset_seconds: null,
|
||||
qry__files_sort: 'created_on',
|
||||
|
||||
// Search stabilization — version bump clears cache and re-runs (Standardized Pattern 2026-01-27).
|
||||
search_version: 0,
|
||||
qry__remote_first: false,
|
||||
|
||||
qry_and__file_count: true, // When true, only sessions with at least 1 file are returned.
|
||||
|
||||
qry_and__file_count: true,
|
||||
save_search_text: true,
|
||||
saved_search__session: null,
|
||||
saved_search__session_location_name: null,
|
||||
fulltext_search_qry_str: null,
|
||||
location_name_qry_str: null,
|
||||
refresh_interval: 0,
|
||||
|
||||
require__presenter_agree: false,
|
||||
require__session_agree: false,
|
||||
// Report display preferences
|
||||
rpt__session_no_files: true,
|
||||
rpt__session_poc_agree: false,
|
||||
rpt__session_no_bio: true,
|
||||
rpt__presenter_agree: true,
|
||||
qry__file_purpose: null,
|
||||
qry__files_min_size: null,
|
||||
qry__session_sort: 'name',
|
||||
qry__presenter_sort: 'name',
|
||||
|
||||
// Content / panel visibility
|
||||
expand__menu_opts: false,
|
||||
show_content__device_description: false,
|
||||
show_content__location_description: false,
|
||||
show_content__location_devices_sessions: null,
|
||||
show_content__event_view: null,
|
||||
show_content__location_qr: false,
|
||||
show_content__presentation_description: false, // Global toggle — applies to all presentations.
|
||||
show_content__presentation_description: false,
|
||||
show_content__presenter_page_help: true,
|
||||
show_content__presenter_view: null,
|
||||
show_content__presenter_qr: false,
|
||||
@@ -160,100 +314,108 @@ export const pres_mgmt_loc_defaults: PresMgmtLocState = {
|
||||
show_content__session_search_room_name: false,
|
||||
show_content__session_view: null,
|
||||
show_content__session_qr: false,
|
||||
hide__session_code: false, // Default visible; toggle in ae_comp__events_menu_opts to hide
|
||||
hide__session_msg: true,
|
||||
hide__session_poc: true,
|
||||
hide__session_poc_biography: true,
|
||||
hide__presenter_biography: true,
|
||||
|
||||
// List/table-specific visibility.
|
||||
hide__session_li_location_field: false,
|
||||
show__session_li_poc_field: false,
|
||||
hide__launcher_link_legacy: true, // Flask version.
|
||||
hide__launcher_link: true, // SvelteKit version.
|
||||
hide__location_link: true,
|
||||
|
||||
show_content__disabled_files: false,
|
||||
show_content__hidden_files: false,
|
||||
show_content__hidden_presentations: false,
|
||||
show_content__hidden_presenters: false,
|
||||
show_content__hidden_sessions: false,
|
||||
|
||||
// List/table column visibility
|
||||
hide__device_code: false,
|
||||
hide__locations_msg: false,
|
||||
hide__session_li_location_field: false,
|
||||
show__session_li_poc_field: false,
|
||||
hide__launcher_link_legacy: true,
|
||||
hide__launcher_link: true,
|
||||
hide__location_link: true,
|
||||
show__direct_download: false,
|
||||
|
||||
// Menu visibility — null means "use server-side default".
|
||||
// Use "hide" prefix for any new additions here.
|
||||
// Menu visibility
|
||||
show_menu__presenter: null,
|
||||
show_menu__session: null,
|
||||
show_menu__session_search: null,
|
||||
show_menu__event_reports: null,
|
||||
|
||||
show_report: null,
|
||||
|
||||
// Opt-out
|
||||
disable_submit__opt_out: true,
|
||||
submit_status__opt_out: null,
|
||||
|
||||
// Scratch space
|
||||
device_kv: {},
|
||||
location_kv: {}
|
||||
location_kv: {},
|
||||
|
||||
// Synced from remote (defaults apply until first event load)
|
||||
label__person_external_id: 'External ID',
|
||||
label__presenter_external_id: 'External ID',
|
||||
label__session_poc_type: 'poc',
|
||||
label__session_poc_name: 'Point of Contact',
|
||||
hide__location_code: false,
|
||||
hide__presentation_code: false,
|
||||
hide__presentation_datetime: false,
|
||||
hide__presentation_description: false,
|
||||
hide__presenter_code: false,
|
||||
hide__presenter_biography: true,
|
||||
hide__session_code: false,
|
||||
hide__session_description: false,
|
||||
hide__session_location: false,
|
||||
hide__session_msg: true,
|
||||
hide__session_poc: true,
|
||||
hide__session_poc_biography: true,
|
||||
hide__session_poc_profile: false,
|
||||
hide__session_poc_profile_pic: false,
|
||||
show__copy_access_link: false,
|
||||
show__email_access_link: false,
|
||||
show__launcher_link: false,
|
||||
show__launcher_link_legacy: false,
|
||||
require__presenter_agree: false,
|
||||
require__session_agree: false,
|
||||
limit__navigation: false,
|
||||
limit__options: false,
|
||||
file_purpose_option_kv: null,
|
||||
hide__report_kv: {}
|
||||
};
|
||||
|
||||
// In-memory pres_mgmt state — resets on page load.
|
||||
export const pres_mgmt_sess_defaults: PresMgmtSessState = {
|
||||
presenter__updated_on: null,
|
||||
session_updated_on: null,
|
||||
|
||||
location_name_qry_str: null,
|
||||
fulltext_search_qry_str: null,
|
||||
status_qry__search: null,
|
||||
|
||||
disable_submit__event_file_obj: true,
|
||||
|
||||
show_form__search: true,
|
||||
show_form__search_results: true,
|
||||
|
||||
show_content__agree_text: false,
|
||||
show_content__presenter_start: false,
|
||||
show_content__presentation_description: false, // Per-presentation (keyed by event_presentation_id_random).
|
||||
|
||||
show_content__presentation_description: false,
|
||||
show_report: null,
|
||||
|
||||
show_field_edit__filename: false, // For file rename.
|
||||
|
||||
show_field_edit__filename: false,
|
||||
new_upload_list: null,
|
||||
files_uploading_count: null,
|
||||
|
||||
qry_limit__files: 75,
|
||||
qry_limit__presentations: 25,
|
||||
qry_limit__presenters: 500,
|
||||
qry_limit__sessions: 100,
|
||||
|
||||
show_fields__presentation: true,
|
||||
show_fields__session: true,
|
||||
|
||||
show_modal__presenter_agree: false,
|
||||
show__session_poc_profile: false,
|
||||
show_modal__session_poc_agree: false,
|
||||
|
||||
show__edit_location: {},
|
||||
show__edit_poc_person: {},
|
||||
|
||||
show__view_alert: {}, // Key-value: show alert by ID.
|
||||
show__edit_alert_msg: {}, // Key-value: show edit alert msg by ID.
|
||||
tmp__alert_msg: {}, // Key-value: temp alert msg content by ID.
|
||||
|
||||
session_qr_url: {}, // Key-value: session_id → URL string.
|
||||
|
||||
show__view_alert: {},
|
||||
show__edit_alert_msg: {},
|
||||
tmp__alert_msg: {},
|
||||
session_qr_url: {},
|
||||
status_rpt: {
|
||||
recent_files: null,
|
||||
presenters_agree: null,
|
||||
presenters_biography: null
|
||||
},
|
||||
|
||||
rpt__session_no_files: true,
|
||||
rpt__session_poc_agree: false, // Default to false for new events.
|
||||
rpt__session_poc_agree: false,
|
||||
rpt__session_no_bio: true,
|
||||
|
||||
rpt__presenter_agree: true,
|
||||
|
||||
tmp_val__filename_no_ext: null // For file rename.
|
||||
tmp_val__filename_no_ext: null
|
||||
};
|
||||
|
||||
@@ -33,6 +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_EVENTS_LOC_VERSION = 1;
|
||||
export const AE_IDAA_LOC_VERSION = 1; // Added 2026-03-30: was missing, no wipe mechanism existed
|
||||
export const AE_PRES_MGMT_LOC_VERSION = 1; // Added 2026-04-02: new standalone PersistedState store
|
||||
|
||||
// Version check side-effect: runs on import, before any persisted() call.
|
||||
// Guard presence of `localStorage` and its functions for safety (SSR, Node flags).
|
||||
@@ -44,6 +45,10 @@ if (
|
||||
_check_and_wipe('ae_loc', AE_LOC_VERSION);
|
||||
_check_and_wipe('ae_events_loc', AE_EVENTS_LOC_VERSION);
|
||||
_check_and_wipe('ae_idaa_loc', AE_IDAA_LOC_VERSION);
|
||||
// ae_pres_mgmt_loc uses PersistedState (runed) which stores raw JSON without a __version
|
||||
// field. The _check_and_wipe mechanism requires __version in the stored data — do NOT
|
||||
// add it here until pres_mgmt_loc_defaults includes __version. For now the key is new
|
||||
// (no stale data exists) so no wipe is needed.
|
||||
}
|
||||
|
||||
function _check_and_wipe(key: string, expected_version: number): void {
|
||||
|
||||
Reference in New Issue
Block a user