Restore Event Session search stability and advance platform-wide string ID standardization
- Restored Event Session search by standardizing on 'event_id' for Dexie queries and implementing dual-layer filtering (local + API guard) to prevent broad results from clobbering filtered views. - Advanced String-Only ID Standardization (Phase 2) by updating generic object processors across all event library modules to support both base IDs and legacy '_random' variants. - Refactored Event Presenter and Presentation components to support standardized '_id_li' props while maintaining backward compatibility. - Standardized common helper identifiers to snake_case (e.g., 'prevent_default') in the Events module. - Verified Staff and Poster email notification logic in the Bulletin Board module. - Updated .gitignore and cleaned up test artifacts.
This commit is contained in:
@@ -290,7 +290,9 @@ async function _process_generic_props<T extends Record<string, any>>({ obj_li, o
|
||||
}
|
||||
}
|
||||
const randomIdKey = `${obj_type}_id_random`;
|
||||
const baseIdKey = `${obj_type}_id`;
|
||||
if (processed_obj[randomIdKey]) (processed_obj as any).id = processed_obj[randomIdKey];
|
||||
else if (processed_obj[baseIdKey]) (processed_obj as any).id = processed_obj[baseIdKey];
|
||||
const group = processed_obj.group ?? '0';
|
||||
const priority = processed_obj.priority ? 1 : 0;
|
||||
const sort = processed_obj.sort ?? '0';
|
||||
|
||||
@@ -313,7 +313,9 @@ async function _process_generic_props<T extends Record<string, any>>({ obj_li, o
|
||||
}
|
||||
}
|
||||
const randomIdKey = `${obj_type}_id_random`;
|
||||
const baseIdKey = `${obj_type}_id`;
|
||||
if (processed_obj[randomIdKey]) (processed_obj as any).id = processed_obj[randomIdKey];
|
||||
else if (processed_obj[baseIdKey]) (processed_obj as any).id = processed_obj[baseIdKey];
|
||||
const group = processed_obj.group ?? '0';
|
||||
const priority = processed_obj.priority ? 1 : 0;
|
||||
const sort = processed_obj.sort ?? '0';
|
||||
|
||||
@@ -382,7 +382,9 @@ async function _process_generic_props<T extends Record<string, any>>({ obj_li, o
|
||||
}
|
||||
}
|
||||
const randomIdKey = `${obj_type}_id_random`;
|
||||
const baseIdKey = `${obj_type}_id`;
|
||||
if (processed_obj[randomIdKey]) (processed_obj as any).id = processed_obj[randomIdKey];
|
||||
else if (processed_obj[baseIdKey]) (processed_obj as any).id = processed_obj[baseIdKey];
|
||||
const group = processed_obj.group ?? '0';
|
||||
const priority = processed_obj.priority ? 1 : 0;
|
||||
const sort = processed_obj.sort ?? '0';
|
||||
|
||||
@@ -294,6 +294,11 @@ export async function search__event_session({
|
||||
else if (enabled === 'not_enabled') search_query.and.push({ field: 'enable', op: 'eq', value: 0 });
|
||||
if (hidden === 'hidden') search_query.and.push({ field: 'hide', op: 'eq', value: 1 });
|
||||
else if (hidden === 'not_hidden') search_query.and.push({ field: 'hide', op: 'eq', value: 0 });
|
||||
|
||||
if (location_name) {
|
||||
search_query.and.push({ field: 'event_location_name', op: 'eq', value: location_name });
|
||||
}
|
||||
|
||||
const result_li = await api.search_ae_obj_v3({ api_cfg, obj_type: 'event_session', search_query, order_by_li, view, limit, offset, log_lvl });
|
||||
if (result_li) {
|
||||
const processed = await process_ae_obj__event_session_props({ obj_li: result_li, log_lvl });
|
||||
@@ -330,7 +335,10 @@ async function _process_generic_props<T extends Record<string, any>>({ obj_li, o
|
||||
}
|
||||
}
|
||||
const randomIdKey = `${obj_type}_id_random`;
|
||||
const baseIdKey = `${obj_type}_id`;
|
||||
if (processed_obj[randomIdKey]) (processed_obj as any).id = processed_obj[randomIdKey];
|
||||
else if (processed_obj[baseIdKey]) (processed_obj as any).id = processed_obj[baseIdKey];
|
||||
|
||||
const group = processed_obj.group ?? '0';
|
||||
const priority = processed_obj.priority ? 1 : 0;
|
||||
const sort = processed_obj.sort ?? '0';
|
||||
|
||||
@@ -16,7 +16,7 @@ This module provides a comprehensive solution for event exhibitors to capture an
|
||||
|
||||
## Data Model
|
||||
|
||||
The core data structures managed by this module are `Exhibit` and `Exhibit_tracking`.
|
||||
The core data structures managed by this module are `Exhibit` and `Exhibit_tracking`. The actual DB table name is event_person_tracking. It was originally intended for generalized "tracking" of a person at an event. This would include other things like session attendance tracking, in addition to exhibitor lead retrieval. However, the initial implementation is focused solely on the lead retrieval use case for exhibitors.
|
||||
|
||||
### Exhibit
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
interface Props {
|
||||
container_class_li?: string | Array<string>;
|
||||
display_mode?: string; // 'default', 'compact', 'minimal', 'launcher'
|
||||
event_presenter_id_li?: Array<string>;
|
||||
event_presenter_id_random_li?: Array<string>;
|
||||
link_to_type: string;
|
||||
link_to_id: string;
|
||||
@@ -12,6 +13,7 @@
|
||||
let {
|
||||
container_class_li = [],
|
||||
display_mode = 'default',
|
||||
event_presenter_id_li = [],
|
||||
event_presenter_id_random_li = [],
|
||||
link_to_type,
|
||||
link_to_id,
|
||||
@@ -33,8 +35,8 @@
|
||||
// let ae_tmp: key_val = {};
|
||||
// let ae_triggers: key_val = {};
|
||||
|
||||
let dq__where_type_id_val: string = `${link_to_type}_id_random`;
|
||||
let dq__where_eq_id_val: string = link_to_id;
|
||||
let dq__where_type_id_val = $derived(`${link_to_type}_id`);
|
||||
let dq__where_eq_id_val = $derived(link_to_id);
|
||||
|
||||
// *** Functions and Logic
|
||||
let lq__event_presenter_obj_li = $derived(
|
||||
@@ -45,6 +47,10 @@
|
||||
.equals(dq__where_eq_id_val)
|
||||
.sortBy('full_name');
|
||||
|
||||
return results;
|
||||
} else if (event_presenter_id_li.length > 0) {
|
||||
let results = await db_events.presenter.bulkGet(event_presenter_id_li);
|
||||
|
||||
return results;
|
||||
} else if (event_presenter_id_random_li.length > 0) {
|
||||
let results = await db_events.presenter.bulkGet(event_presenter_id_random_li);
|
||||
|
||||
@@ -91,7 +91,7 @@
|
||||
if (event_id && !$events_loc.pres_mgmt.fulltext_search_qry_str && !$events_loc.pres_mgmt.location_name_qry_str) {
|
||||
if (log_lvl) console.log(`Session Page LQ: Fallback search for event: ${event_id}`);
|
||||
return await db_events.session
|
||||
.where('event_id_random')
|
||||
.where('event_id')
|
||||
.equals(event_id)
|
||||
.limit(50)
|
||||
.sortBy('name');
|
||||
@@ -124,9 +124,7 @@
|
||||
const params = search_params;
|
||||
if (search_debounce_timer) clearTimeout(search_debounce_timer);
|
||||
search_debounce_timer = setTimeout(() => {
|
||||
untrack(() => {
|
||||
handle_search_refresh(params);
|
||||
});
|
||||
handle_search_refresh(params);
|
||||
}, 300);
|
||||
return () => {
|
||||
if (search_debounce_timer) clearTimeout(search_debounce_timer);
|
||||
@@ -157,7 +155,7 @@
|
||||
try {
|
||||
if (event_id) {
|
||||
let local_results = await db_events.session
|
||||
.where('event_id_random')
|
||||
.where('event_id')
|
||||
.equals(event_id)
|
||||
.filter(session => {
|
||||
if (location_name && session.event_location_name !== location_name) return false;
|
||||
@@ -180,7 +178,7 @@
|
||||
.toArray();
|
||||
|
||||
local_results.sort((a, b) => (a.name ?? '').localeCompare(b.name ?? ''));
|
||||
const local_ids = local_results.map(s => s.id || s.event_session_id_random).filter(Boolean);
|
||||
const local_ids = local_results.map(s => s.id || s.event_session_id).filter(Boolean);
|
||||
|
||||
if (current_search_id === last_search_id) {
|
||||
if (log_lvl) console.log(`[Session Search #${current_search_id}] Fast Path found ${local_ids.length} items locally.`);
|
||||
@@ -215,8 +213,26 @@
|
||||
});
|
||||
|
||||
if (current_search_id === last_search_id) {
|
||||
const api_results = results || [];
|
||||
const api_ids = api_results.map((s: any) => s.id || s.event_session_id_random).filter(Boolean);
|
||||
let api_results = results || [];
|
||||
|
||||
// Client-side Filter Guard: Ensure API results match local criteria (Backup filter)
|
||||
api_results = api_results.filter(session => {
|
||||
if (location_name && session.event_location_name !== location_name) return false;
|
||||
if (qry_str) {
|
||||
const name = (session.name ?? '').toLowerCase();
|
||||
const code = (session.code ?? '').toLowerCase();
|
||||
const description = (session.description ?? '').toLowerCase();
|
||||
const qry_string = (session.default_qry_str ?? '').toLowerCase();
|
||||
const match = name.includes(qry_str) ||
|
||||
code.includes(qry_str) ||
|
||||
description.includes(qry_str) ||
|
||||
qry_string.includes(qry_str);
|
||||
if (!match) return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
const api_ids = api_results.map((s: any) => s.id || s.event_session_id).filter(Boolean);
|
||||
|
||||
untrack(() => {
|
||||
$events_slct.event_session_obj_li = api_results;
|
||||
@@ -251,7 +267,7 @@
|
||||
$events_loc.pres_mgmt.search_version++;
|
||||
}
|
||||
|
||||
function preventDefault<T extends Event>(fn: (event: T) => void) {
|
||||
function prevent_default<T extends Event>(fn: (event: T) => void) {
|
||||
return function (event: T) {
|
||||
event.preventDefault();
|
||||
fn(event);
|
||||
@@ -325,7 +341,7 @@
|
||||
{#if !$events_loc.pres_mgmt.show_content__event_view || $events_loc.pres_mgmt.show_content__event_view == 'default'}
|
||||
<div class="ae_container_actions">
|
||||
<form
|
||||
onsubmit={preventDefault(() => handle_search_trigger())}
|
||||
onsubmit={prevent_default(() => handle_search_trigger())}
|
||||
autocomplete="off"
|
||||
class="form grow flex flex-row flex-wrap gap-1 justify-center items-center w-full"
|
||||
>
|
||||
@@ -487,9 +503,9 @@
|
||||
<div class="overflow-x-auto w-max max-w-full">
|
||||
<Element_manage_event_file_li_wrap
|
||||
link_to_type={'event'}
|
||||
link_to_id={$lq__event_obj?.event_id_random}
|
||||
allow_basic={$events_loc.auth__kv.session[$lq__event_obj?.event_id_random]}
|
||||
allow_moderator={$events_loc.auth__kv.session[$lq__event_obj?.event_id_random]}
|
||||
link_to_id={$lq__event_obj?.event_id}
|
||||
allow_basic={$events_loc.auth__kv.session[$lq__event_obj?.event_id]}
|
||||
allow_moderator={$events_loc.auth__kv.session[$lq__event_obj?.event_id]}
|
||||
container_class_li={''}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -463,8 +463,8 @@
|
||||
{#if event_presentation_obj?.event_presentation_id}
|
||||
<Comp_event_presenter_obj_li
|
||||
link_to_type={'event_presentation'}
|
||||
link_to_id={event_presentation_obj?.event_presentation_id}
|
||||
event_presenter_id_random_li={[]}
|
||||
link_to_id={event_presentation_obj.event_presentation_id}
|
||||
event_presenter_id_li={[]}
|
||||
log_lvl={2}
|
||||
></Comp_event_presenter_obj_li>
|
||||
{/if}
|
||||
|
||||
Reference in New Issue
Block a user