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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user