- Split search query by spaces - Apply AND logic: all words must match - Single word: LIKE '%word%' - Multi-word: LIKE '%word1%' AND LIKE '%word2%' Example: 'scott idem' now searches for both 'scott' AND 'idem' Previously searched for literal 'scott idem' phrase which failed. Fixes search bug discovered during Playwright test development.
650 lines
20 KiB
TypeScript
650 lines
20 KiB
TypeScript
import type { key_val } from '$lib/stores/ae_stores';
|
|
import { api } from '$lib/api/api';
|
|
|
|
import { db_save_ae_obj_li__ae_obj } from '$lib/ae_core/core__idb_dexie';
|
|
import { db_events } from '$lib/ae_events/db_events';
|
|
import type { ae_EventBadge } from '$lib/types/ae_types';
|
|
|
|
import { load_ae_obj_id__event_badge_template } from '$lib/ae_events/ae_events__event_badge_template';
|
|
|
|
const ae_promises: key_val = {};
|
|
|
|
// Updated 2026-01-02
|
|
/**
|
|
* load_ae_obj_id__event_badge - Load a single event badge by ID
|
|
* Related Files:
|
|
* - src/lib/ae_events/db_events.ts (Dexie Interface)
|
|
* - src/routes/events/[event_id]/(badges)/badges/[badge_id]/+page.svelte (View)
|
|
* - src/routes/events/[event_id]/settings/+page.svelte (Admin Operations)
|
|
*/
|
|
export async function load_ae_obj_id__event_badge({
|
|
api_cfg,
|
|
event_badge_id,
|
|
event_id, // This event_id should not be needed here... 2026-02-04
|
|
view = 'base',
|
|
inc_template = true,
|
|
try_cache = true,
|
|
log_lvl = 0
|
|
}: {
|
|
api_cfg: any;
|
|
event_badge_id: string;
|
|
event_id?: string;
|
|
view?: string;
|
|
inc_template?: boolean;
|
|
try_cache?: boolean;
|
|
log_lvl?: number;
|
|
}): Promise<ae_EventBadge | null> {
|
|
if (log_lvl) {
|
|
console.log(`*** load_ae_obj_id__event_badge() *** event_badge_id=${event_badge_id}`);
|
|
}
|
|
|
|
try {
|
|
ae_promises.load__event_badge_obj = await api
|
|
.get_ae_obj_v3({
|
|
api_cfg,
|
|
obj_type: 'event_badge',
|
|
obj_id: event_badge_id,
|
|
view,
|
|
log_lvl
|
|
});
|
|
|
|
if (ae_promises.load__event_badge_obj) {
|
|
if (try_cache) {
|
|
// In theory we should be able to use the event_id found in the Badge load object. 2026-02-04
|
|
// This keeps coming up as undefined: ae_promises.load__event_badge_obj.event_id
|
|
if (log_lvl) console.log(`Saving to local cache... Event ID: ${event_id} or ${ae_promises.load__event_badge_obj.event_id}`);
|
|
const processed_obj_li = await process_ae_obj__event_badge_props({
|
|
obj_li: [ae_promises.load__event_badge_obj],
|
|
event_id: event_id || ae_promises.load__event_badge_obj.event_id,
|
|
log_lvl
|
|
});
|
|
await db_save_ae_obj_li__ae_obj({
|
|
db_instance: db_events,
|
|
table_name: 'badge',
|
|
obj_li: processed_obj_li,
|
|
properties_to_save,
|
|
log_lvl
|
|
});
|
|
// Return the processed object (matches what was saved to IDB)
|
|
ae_promises.load__event_badge_obj = processed_obj_li[0];
|
|
}
|
|
} else {
|
|
console.log('No results returned from API.');
|
|
if (try_cache) {
|
|
if (log_lvl) console.log('Attempting to load from local cache...');
|
|
ae_promises.load__event_badge_obj = await db_events.badge.get(event_badge_id);
|
|
}
|
|
}
|
|
} catch (error: any) {
|
|
console.log('API request failed.', error);
|
|
if (try_cache) {
|
|
if (log_lvl) console.log('Attempting to load from local cache after error...');
|
|
ae_promises.load__event_badge_obj = await db_events.badge.get(event_badge_id);
|
|
} else {
|
|
ae_promises.load__event_badge_obj = null;
|
|
}
|
|
}
|
|
|
|
if (inc_template && ae_promises.load__event_badge_obj) {
|
|
// Load the templates for the event badge
|
|
const current_template_id = ae_promises.load__event_badge_obj.event_badge_template_id;
|
|
if (current_template_id) {
|
|
ae_promises.load__event_badge_obj.event_badge_template = await load_ae_obj_id__event_badge_template({
|
|
api_cfg: api_cfg,
|
|
event_badge_template_id: current_template_id,
|
|
try_cache: try_cache,
|
|
log_lvl: log_lvl
|
|
});
|
|
}
|
|
}
|
|
|
|
return ae_promises.load__event_badge_obj;
|
|
}
|
|
|
|
// Updated 2026-01-02
|
|
export async function load_ae_obj_li__event_badge({
|
|
api_cfg,
|
|
event_id,
|
|
inc_template = true, // This should probably be false.
|
|
enabled = 'enabled',
|
|
hidden = 'not_hidden',
|
|
view = 'default',
|
|
limit = 99,
|
|
offset = 0,
|
|
order_by_li = { priority: 'DESC', sort: 'DESC', updated_on: 'DESC', created_on: 'DESC' },
|
|
params = {},
|
|
try_cache = true,
|
|
log_lvl = 0
|
|
}: {
|
|
api_cfg: any;
|
|
event_id: string;
|
|
inc_template?: boolean;
|
|
enabled?: 'enabled' | 'all' | 'not_enabled' | undefined;
|
|
hidden?: 'hidden' | 'all' | 'not_hidden' | undefined;
|
|
view?: string;
|
|
limit?: number;
|
|
offset?: number;
|
|
order_by_li?: key_val;
|
|
params?: key_val;
|
|
try_cache?: boolean;
|
|
log_lvl?: number;
|
|
}): Promise<ae_EventBadge[]> {
|
|
if (log_lvl) {
|
|
console.log(`*** load_ae_obj_li__event_badge() *** event_id=${event_id}`);
|
|
}
|
|
|
|
try {
|
|
ae_promises.load__event_badge_obj_li = await api
|
|
.get_ae_obj_li_v3({
|
|
api_cfg,
|
|
obj_type: 'event_badge',
|
|
for_obj_type: 'event',
|
|
for_obj_id: event_id,
|
|
enabled: enabled,
|
|
hidden: hidden,
|
|
view: view,
|
|
order_by_li: order_by_li,
|
|
limit: limit,
|
|
offset: offset,
|
|
log_lvl: log_lvl
|
|
});
|
|
|
|
if (ae_promises.load__event_badge_obj_li) {
|
|
if (try_cache) {
|
|
const processed_obj_li = await process_ae_obj__event_badge_props({
|
|
obj_li: ae_promises.load__event_badge_obj_li,
|
|
event_id,
|
|
log_lvl
|
|
});
|
|
await db_save_ae_obj_li__ae_obj({
|
|
db_instance: db_events,
|
|
table_name: 'badge',
|
|
obj_li: processed_obj_li,
|
|
properties_to_save,
|
|
log_lvl
|
|
});
|
|
// Return the processed list (matches what was saved to IDB)
|
|
ae_promises.load__event_badge_obj_li = processed_obj_li;
|
|
}
|
|
} else {
|
|
console.log('No results returned from API.');
|
|
if (try_cache) {
|
|
if (log_lvl) console.log('Attempting to load from local cache...');
|
|
ae_promises.load__event_badge_obj_li = await db_events.badge
|
|
.where('event_id').equals(event_id)
|
|
.toArray();
|
|
} else {
|
|
ae_promises.load__event_badge_obj_li = [];
|
|
}
|
|
}
|
|
} catch (error: any) {
|
|
console.log('API request failed.', error);
|
|
if (try_cache) {
|
|
if (log_lvl) console.log('Attempting to load from local cache after error...');
|
|
ae_promises.load__event_badge_obj_li = await db_events.badge
|
|
.where('event_id').equals(event_id)
|
|
.toArray();
|
|
} else {
|
|
ae_promises.load__event_badge_obj_li = [];
|
|
}
|
|
}
|
|
|
|
if (inc_template && ae_promises.load__event_badge_obj_li) {
|
|
for (const badge_obj of ae_promises.load__event_badge_obj_li) {
|
|
const current_template_id = badge_obj.event_badge_template_id;
|
|
if (current_template_id) {
|
|
badge_obj.event_badge_template = await load_ae_obj_id__event_badge_template({
|
|
api_cfg: api_cfg,
|
|
event_badge_template_id: current_template_id,
|
|
try_cache: try_cache,
|
|
log_lvl: log_lvl
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
return ae_promises.load__event_badge_obj_li;
|
|
}
|
|
|
|
// Updated 2026-01-06
|
|
export async function create_ae_obj__event_badge({
|
|
api_cfg,
|
|
event_id,
|
|
data_kv,
|
|
params = {},
|
|
try_cache = true,
|
|
log_lvl = 0
|
|
}: {
|
|
api_cfg: any;
|
|
event_id: string;
|
|
data_kv: key_val;
|
|
params?: key_val;
|
|
try_cache?: boolean;
|
|
log_lvl?: number;
|
|
}): Promise<ae_EventBadge | null> {
|
|
if (log_lvl) {
|
|
console.log(`*** create_ae_obj__event_badge() *** event_id=${event_id}`);
|
|
}
|
|
|
|
const result = await api.create_nested_obj_v3({
|
|
api_cfg,
|
|
parent_type: 'event',
|
|
parent_id: event_id,
|
|
child_type: 'event_badge',
|
|
fields: data_kv,
|
|
params,
|
|
log_lvl
|
|
});
|
|
|
|
if (result && try_cache) {
|
|
const processed_obj_li = await process_ae_obj__event_badge_props({
|
|
obj_li: [result],
|
|
event_id,
|
|
log_lvl
|
|
});
|
|
await db_save_ae_obj_li__ae_obj({
|
|
db_instance: db_events,
|
|
table_name: 'badge',
|
|
obj_li: processed_obj_li,
|
|
properties_to_save,
|
|
log_lvl
|
|
});
|
|
// Return the processed object (matches what was saved to IDB)
|
|
return processed_obj_li[0];
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
// Updated 2026-01-06
|
|
export async function delete_ae_obj_id__event_badge({
|
|
api_cfg,
|
|
event_id,
|
|
event_badge_id,
|
|
method = 'delete',
|
|
params = {},
|
|
try_cache = true,
|
|
log_lvl = 0
|
|
}: {
|
|
api_cfg: any;
|
|
event_id: string;
|
|
event_badge_id: string;
|
|
method?: 'delete' | 'soft_delete' | 'disable' | 'hide';
|
|
params?: key_val;
|
|
try_cache?: boolean;
|
|
log_lvl?: number;
|
|
}) {
|
|
if (log_lvl) {
|
|
console.log(`*** delete_ae_obj_id__event_badge() *** event_badge_id=${event_badge_id}`);
|
|
}
|
|
|
|
const result = await api.delete_nested_ae_obj_v3({
|
|
api_cfg,
|
|
parent_type: 'event',
|
|
parent_id: event_id,
|
|
child_type: 'event_badge',
|
|
child_id: event_badge_id,
|
|
method,
|
|
params,
|
|
log_lvl
|
|
});
|
|
|
|
if (try_cache) {
|
|
await db_events.badge.delete(event_badge_id);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
// Updated 2026-01-06
|
|
export async function update_ae_obj__event_badge({
|
|
api_cfg,
|
|
event_id,
|
|
event_badge_id,
|
|
data_kv,
|
|
params = {},
|
|
try_cache = true,
|
|
log_lvl = 0
|
|
}: {
|
|
api_cfg: any;
|
|
event_id: string;
|
|
event_badge_id: string;
|
|
data_kv: key_val;
|
|
params?: key_val;
|
|
try_cache?: boolean;
|
|
log_lvl?: number;
|
|
}): Promise<ae_EventBadge | null> {
|
|
if (log_lvl) {
|
|
console.log(`*** update_ae_obj__event_badge() *** event_badge_id=${event_badge_id}`);
|
|
}
|
|
|
|
const result = await api.update_nested_obj_v3({
|
|
api_cfg,
|
|
parent_type: 'event',
|
|
parent_id: event_id,
|
|
child_type: 'event_badge',
|
|
child_id: event_badge_id,
|
|
fields: data_kv,
|
|
params,
|
|
log_lvl
|
|
});
|
|
|
|
if (result && try_cache) {
|
|
const processed_obj_li = await process_ae_obj__event_badge_props({
|
|
obj_li: [result],
|
|
event_id,
|
|
log_lvl
|
|
});
|
|
await db_save_ae_obj_li__ae_obj({
|
|
db_instance: db_events,
|
|
table_name: 'badge',
|
|
obj_li: processed_obj_li,
|
|
properties_to_save,
|
|
log_lvl
|
|
});
|
|
// Return the processed object (matches what was saved to IDB)
|
|
return processed_obj_li[0];
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
// Updated 2026-01-27 to Restore Full Aether Search Logic
|
|
export async function search__event_badge({
|
|
api_cfg,
|
|
event_id,
|
|
type_code = null,
|
|
printed_status = 'all', // 'all', 'printed', 'not_printed'
|
|
affiliations_qry_str = null,
|
|
fulltext_search_qry_str = null,
|
|
like_search_qry_str = null,
|
|
external_event_id = null,
|
|
enabled = 'enabled',
|
|
hidden = 'not_hidden',
|
|
view = 'base',
|
|
limit = 25,
|
|
offset = 0,
|
|
order_by_li = {
|
|
given_name: 'ASC',
|
|
family_name: 'ASC',
|
|
updated_on: 'DESC',
|
|
created_on: 'DESC'
|
|
},
|
|
try_cache = true,
|
|
log_lvl = 0
|
|
}: {
|
|
api_cfg: any;
|
|
event_id: string;
|
|
type_code?: null | string;
|
|
printed_status?: 'all' | 'printed' | 'not_printed' | undefined;
|
|
affiliations_qry_str?: null | string;
|
|
external_event_id?: null | string;
|
|
fulltext_search_qry_str?: null | string;
|
|
like_search_qry_str?: null | string;
|
|
enabled?: 'enabled' | 'all' | 'not_enabled' | undefined;
|
|
hidden?: 'hidden' | 'all' | 'not_hidden' | undefined;
|
|
view?: string;
|
|
limit?: number;
|
|
offset?: number;
|
|
order_by_li?: key_val;
|
|
try_cache?: boolean;
|
|
log_lvl?: number;
|
|
}): Promise<ae_EventBadge[] | false> {
|
|
if (log_lvl) {
|
|
console.log(`*** search__event_badge() *** event_id=${event_id} ft=${fulltext_search_qry_str}`);
|
|
}
|
|
|
|
const search_query: any = {
|
|
q: '',
|
|
and: [{ field: 'event_id', op: 'eq', value: event_id }]
|
|
};
|
|
|
|
const params: key_val = {};
|
|
|
|
// Standardized Text Search Pattern (V3 API)
|
|
// NOTE: Using 'default_qry_str' (Strict DB Column)
|
|
// Multi-word support: Split query by spaces and search for all words (AND logic)
|
|
if (fulltext_search_qry_str && fulltext_search_qry_str.trim().length > 0) {
|
|
const qry = fulltext_search_qry_str.trim();
|
|
const words = qry.split(/\s+/).filter(w => w.length > 0);
|
|
|
|
if (words.length === 1) {
|
|
// Single word: use simple LIKE
|
|
search_query.and.push({ field: 'default_qry_str', op: 'like', value: `%${words[0]}%` });
|
|
} else if (words.length > 1) {
|
|
// Multiple words: each word must match (AND logic)
|
|
for (const word of words) {
|
|
search_query.and.push({ field: 'default_qry_str', op: 'like', value: `%${word}%` });
|
|
}
|
|
}
|
|
|
|
params['lk_qry'] = params['lk_qry'] || {};
|
|
params['lk_qry']['default_qry_str'] = qry;
|
|
}
|
|
|
|
if (affiliations_qry_str && affiliations_qry_str.trim().length > 0) {
|
|
const qry = affiliations_qry_str.trim();
|
|
search_query.and.push({ field: 'affiliations', op: 'like', value: `%${qry}%` });
|
|
params['lk_qry'] = params['lk_qry'] || {};
|
|
params['lk_qry']['affiliations'] = qry;
|
|
}
|
|
|
|
if (like_search_qry_str) {
|
|
params['lk_qry'] = params['lk_qry'] || {};
|
|
params['lk_qry']['default_qry_str'] = like_search_qry_str;
|
|
}
|
|
|
|
if (external_event_id) {
|
|
search_query.and.push({ field: 'external_event_id', op: 'eq', value: external_event_id });
|
|
}
|
|
|
|
if (type_code) {
|
|
search_query.and.push({ field: 'badge_type_code', op: 'eq', value: type_code });
|
|
}
|
|
|
|
if (printed_status === 'printed') {
|
|
search_query.and.push({ field: 'print_count', op: 'gt', value: 0 });
|
|
} else if (printed_status === 'not_printed') {
|
|
search_query.and.push({ field: 'print_count', op: 'eq', value: 0 });
|
|
}
|
|
|
|
if (enabled === 'enabled') search_query.and.push({ field: 'enable', op: 'eq', value: true });
|
|
else if (enabled === 'not_enabled') search_query.and.push({ field: 'enable', op: 'eq', value: false });
|
|
|
|
if (hidden === 'hidden') search_query.and.push({ field: 'hide', op: 'eq', value: true });
|
|
else if (hidden === 'not_hidden') search_query.and.push({ field: 'hide', op: 'eq', value: false });
|
|
|
|
ae_promises.search__event_badge_obj_li = await api
|
|
.search_ae_obj_v3({
|
|
api_cfg: api_cfg,
|
|
obj_type: 'event_badge',
|
|
search_query,
|
|
params,
|
|
enabled,
|
|
hidden,
|
|
view,
|
|
order_by_li,
|
|
limit,
|
|
offset,
|
|
log_lvl
|
|
})
|
|
.then(async function (badge_obj_li_get_result) {
|
|
// Handle both direct array and {data: []} envelope
|
|
let result_li: ae_EventBadge[] = [];
|
|
if (Array.isArray(badge_obj_li_get_result)) {
|
|
result_li = badge_obj_li_get_result;
|
|
} else if (badge_obj_li_get_result?.data && Array.isArray(badge_obj_li_get_result.data)) {
|
|
result_li = badge_obj_li_get_result.data;
|
|
}
|
|
|
|
if (result_li.length > 0) {
|
|
if (try_cache) {
|
|
const processed_obj_li = await process_ae_obj__event_badge_props({
|
|
obj_li: result_li,
|
|
event_id,
|
|
log_lvl
|
|
});
|
|
await db_save_ae_obj_li__ae_obj({
|
|
db_instance: db_events,
|
|
table_name: 'badge',
|
|
obj_li: processed_obj_li,
|
|
properties_to_save,
|
|
log_lvl
|
|
});
|
|
return processed_obj_li; // Return processed data (matches saved IDB data)
|
|
}
|
|
return result_li; // No cache: return raw API results
|
|
} else {
|
|
return [];
|
|
}
|
|
});
|
|
return ae_promises.search__event_badge_obj_li;
|
|
}
|
|
|
|
export const qry__event_badge = search__event_badge;
|
|
|
|
// Updated 2025-10-06
|
|
export const properties_to_save = [
|
|
'id',
|
|
'event_badge_id',
|
|
'event_id',
|
|
'event_badge_template_id',
|
|
'pronouns',
|
|
'informal_name',
|
|
'title_names',
|
|
'given_name',
|
|
'middle_name',
|
|
'family_name',
|
|
'designations',
|
|
'professional_title',
|
|
'professional_title_override',
|
|
'full_name',
|
|
'full_name_override',
|
|
'affiliations',
|
|
'affiliations_override',
|
|
'email',
|
|
'email_override',
|
|
'address_line_1',
|
|
'address_line_2',
|
|
'address_line_3',
|
|
'city',
|
|
'country_subdivision_code',
|
|
'state_province',
|
|
'state_province_abb',
|
|
'postal_code',
|
|
'country_alpha_2_code',
|
|
'country',
|
|
'full_address',
|
|
'location',
|
|
'location_override',
|
|
'query_str',
|
|
'badge_type',
|
|
'badge_type_code',
|
|
'badge_type_override',
|
|
'badge_type_code_override',
|
|
'external_event_id',
|
|
'external_id',
|
|
'external_person_id',
|
|
'default_qry_str',
|
|
'alert',
|
|
'enable',
|
|
'hide',
|
|
'priority',
|
|
'sort',
|
|
'group',
|
|
'notes',
|
|
'created_on',
|
|
'updated_on',
|
|
'print_count',
|
|
'print_first_datetime',
|
|
'print_last_datetime',
|
|
'tmp_sort_1',
|
|
'tmp_sort_2',
|
|
'person_external_id',
|
|
'person_external_sys_id',
|
|
'person_given_name',
|
|
'person_family_name',
|
|
'person_full_name',
|
|
'person_professional_title',
|
|
'person_affiliations',
|
|
'person_primary_email',
|
|
'person_passcode'
|
|
];
|
|
|
|
/**
|
|
* NON-EXPORTED LOCAL HELPER
|
|
*/
|
|
async function _process_generic_props<T extends Record<string, any>>({
|
|
obj_li,
|
|
obj_type,
|
|
log_lvl = 0,
|
|
specific_processor
|
|
}: {
|
|
obj_li: T[];
|
|
obj_type: string;
|
|
log_lvl?: number;
|
|
specific_processor?: (obj: T) => Promise<T> | T;
|
|
}): Promise<T[]> {
|
|
if (!obj_li || obj_li.length === 0) return [];
|
|
|
|
const processed_obj_li: T[] = [];
|
|
|
|
for (const original_obj of obj_li) {
|
|
let processed_obj = { ...original_obj };
|
|
|
|
for (const key in processed_obj) {
|
|
if (key.endsWith('_random')) {
|
|
const newKey = key.slice(0, -7);
|
|
(processed_obj as any)[newKey] = processed_obj[key];
|
|
}
|
|
}
|
|
const randomIdKey = `${obj_type}_id`;
|
|
if (processed_obj[randomIdKey]) {
|
|
(processed_obj as any).id = processed_obj[randomIdKey];
|
|
}
|
|
|
|
const group = processed_obj.group ?? '0';
|
|
const priority = processed_obj.priority ? 1 : 0;
|
|
const sort = processed_obj.sort ?? '0';
|
|
const updated = processed_obj.updated_on ?? processed_obj.created_on ?? new Date(0).toISOString();
|
|
const name = processed_obj.name ?? '';
|
|
|
|
(processed_obj as any).tmp_sort_1 = `${group}_${priority}_${sort}_${updated}`;
|
|
(processed_obj as any).tmp_sort_2 = `${group}_${priority}_${sort}_${name}_${updated}`;
|
|
|
|
if (specific_processor) {
|
|
processed_obj = await Promise.resolve(specific_processor(processed_obj));
|
|
}
|
|
|
|
processed_obj_li.push(processed_obj as T);
|
|
}
|
|
|
|
return processed_obj_li;
|
|
}
|
|
|
|
// Updated 2025-10-06
|
|
export async function process_ae_obj__event_badge_props({
|
|
obj_li,
|
|
event_id,
|
|
log_lvl = 0
|
|
}: {
|
|
obj_li: any[];
|
|
event_id?: string;
|
|
log_lvl?: number;
|
|
}) {
|
|
return _process_generic_props({
|
|
obj_li,
|
|
obj_type: 'event_badge',
|
|
log_lvl,
|
|
specific_processor: (obj) => {
|
|
if (log_lvl) {
|
|
console.log(`*** process_ae_obj__event_badge_props() *** event_id=${event_id}`);
|
|
}
|
|
if (event_id) {
|
|
if (!obj.event_id) obj.event_id = event_id;
|
|
// if (!obj.event_id_random) obj.event_id_random = event_id;
|
|
}
|
|
return obj;
|
|
}
|
|
});
|
|
} |