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:
@@ -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() ***');
|
||||
|
||||
|
||||
Reference in New Issue
Block a user