refactor(search): standardize debounced reactive search across modules

- Standardized the search pattern using Svelte 5 debounced $effects in Recovery Meetings, Badge Search, and Journals to eliminate manual triggers and stuttering.
- Fixed a bug in 'ae_idaa_comp__event_obj_li.svelte' where the Results count was inconsistent with the displayed list by implementing a derived 'visible_event_obj_li' state.
- Hardened 'ae_idaa_comp__event_obj_li_wrapper.svelte' to filter out 'undefined' entries from database 'bulkGet' calls.
- Cleaned up legacy search handling code in 'ae_idaa_comp__event_obj_qry.svelte'.
- Updated 'TODO.md' and 'GEMINI.md' to reflect search logic hardening accomplishments.
This commit is contained in:
Scott Idem
2026-01-27 13:08:11 -05:00
parent b837e6d0f8
commit 055d8e7816
8 changed files with 258 additions and 787 deletions

View File

@@ -165,65 +165,81 @@
};
}
// Trigger doing a search query for event badges
// Debounced Search Logic (Refactored 2026-01-27)
let search_debounce_timer: any = null;
let last_search_id = 0;
$effect(() => {
if (ae_triggers.event_badge_qry) {
ae_triggers.event_badge_qry = false;
search_status = 'loading';
search_complete = false;
event_badge_id_li = [];
// Reactive dependencies
const s_qry_str = qry_str;
const s_qry_type_code = qry_type_code;
const s_qry_printed_status = qry_printed_status;
const s_qry_affiliations = qry_affiliations;
const s_qry_sort_order = qry_sort_order;
const s_event_id = event_id;
const s_trigger = ae_triggers.event_badge_qry;
// qry_str = $events_loc.badges.fulltext_search_qry_str ?? '';
// qry_type_code = $events_sess.badges.search_badge_type_code ?? '';
// Debounce search
if (search_debounce_timer) clearTimeout(search_debounce_timer);
// Manual trigger or threshold check for automatic search
const should_search = s_trigger ||
s_qry_str.length === 0 ||
s_qry_str.length >= 3 ||
s_qry_affiliations.length >= 3;
if (log_lvl) {
console.log(
`Triggered: event_badge_qry: ft search qry str:=${$events_loc.badges.fulltext_search_qry_str} sort order:=`,
computed_order_by_li
);
}
// ae_promises.load__event_badge_obj_li = events_func.qry__event_badge({
ae_promises.load__event_badge_obj_li = events_func
.search__event_badge({
api_cfg: $ae_api,
event_id: event_id,
fulltext_search_qry_str: qry_str,
type_code: qry_type_code,
printed_status: qry_printed_status,
affiliations_qry_str: qry_affiliations,
order_by_li: computed_order_by_li,
limit: search_limit,
log_lvl: 2
})
.then(function (search_results) {
search_status = 'processing';
let tmp_event_badge_id_li = []; // This is to prevent the array from constantly updating and triggering the liveQuery.
for (let i = 0; i < search_results.length; i++) {
let event_badge_obj = search_results[i];
let event_badge_id_random = event_badge_obj.event_badge_id_random;
if (log_lvl) {
console.log(
`Found badge: ${event_badge_obj.full_name}, id_random: ${event_badge_id_random}`
);
}
tmp_event_badge_id_li.push(event_badge_id_random);
}
event_badge_id_li = tmp_event_badge_id_li;
console.log('event_badge_id_li', event_badge_id_li);
$events_sess.badge_li = search_results;
return search_results;
})
.finally(() => {
search_status = 'done';
search_complete = true;
});
if (should_search) {
search_debounce_timer = setTimeout(() => {
ae_triggers.event_badge_qry = false;
handle_search_refresh();
}, 400);
}
return () => {
if (search_debounce_timer) clearTimeout(search_debounce_timer);
};
});
async function handle_search_refresh() {
const current_search_id = ++last_search_id;
if (log_lvl) console.log(`[Badge Search #${current_search_id}] ft=${qry_str}`);
search_status = 'loading';
search_complete = false;
try {
const results = await events_func.search__event_badge({
api_cfg: $ae_api,
event_id: event_id,
fulltext_search_qry_str: qry_str,
type_code: qry_type_code,
printed_status: qry_printed_status,
affiliations_qry_str: qry_affiliations,
order_by_li: computed_order_by_li,
limit: search_limit,
log_lvl: 0
});
if (current_search_id === last_search_id) {
let tmp_event_badge_id_li = results.map((b: any) => b.event_badge_id_random);
event_badge_id_li = tmp_event_badge_id_li;
$events_sess.badge_li = results;
search_status = 'done';
search_complete = true;
if (log_lvl) console.log(`[Badge Search #${current_search_id}] Done. Found ${results.length} results.`);
}
} catch (error) {
if (current_search_id === last_search_id) {
console.error('Badge search failed:', error);
search_status = 'error';
search_complete = true;
}
}
}
function handle_qr_scan_result(event: CustomEvent) {
console.log('*** handle_qr_scan_result() ***');