fix(idaa): fix country/subdivision/timezone dropdowns — switch to in-memory sort
- Country and state/province fields were showing as plain text inputs because liveQuery used orderBy() on non-indexed columns, causing silent Dexie errors that left the store as undefined indefinitely. - Fix: replaced orderBy() with toArray() + in-memory sort across all three lookup types (country, country_subdivision, time_zone). - Sort convention matches Aether backend: sort DESC (higher = first, NULL=0 last), then name ASC — puts priority entries at the top. - Added db_lookups.ts (IDB schema for lookup tables) and updated core__countries, core__country_subdivisions, core__time_zones to IDB-backed SWR pattern. - Affected: archive edit, archive content edit, recovery meeting edit. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -7,6 +7,8 @@
|
||||
import type { key_val } from '$lib/stores/ae_stores';
|
||||
import { ae_util } from '$lib/ae_utils/ae_utils';
|
||||
import { core_func } from '$lib/ae_core/ae_core_functions';
|
||||
import { liveQuery } from 'dexie';
|
||||
import { db_lookups } from '$lib/ae_core/db_lookups';
|
||||
import {
|
||||
ae_snip,
|
||||
ae_loc,
|
||||
@@ -106,56 +108,21 @@
|
||||
);
|
||||
}
|
||||
|
||||
let lu_time_zone_list: any = $state(
|
||||
localStorage.getItem('lu_time_zone_list')
|
||||
? JSON.parse(localStorage.getItem('lu_time_zone_list') as string)
|
||||
: []
|
||||
// Timezone lookup — reactive IDB query; background refresh handled by liveQuery + TTL
|
||||
// Sort: sort DESC (higher = first, NULL=0 last), then name ASC — matches Aether backend convention.
|
||||
const lq__lu_time_zone = liveQuery(() =>
|
||||
db_lookups.lu_time_zone.toArray().then(arr =>
|
||||
arr.sort((a, b) => {
|
||||
const s_diff = Number(b['sort'] ?? 0) - Number(a['sort'] ?? 0);
|
||||
if (s_diff !== 0) return s_diff;
|
||||
return (a.name ?? '').localeCompare(b.name ?? '');
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
onMount(() => {
|
||||
$ae_loc.lu_time_zone_list = [];
|
||||
// $ae_loc.lu_time_zone_list = [];
|
||||
// lu_time_zone_list = [];
|
||||
if (lu_time_zone_list && lu_time_zone_list.length > 0) {
|
||||
// console.log('Already have time zone list!', lu_time_zone_list);
|
||||
} else {
|
||||
console.log('No time zone list');
|
||||
|
||||
let lu_time_zone_li_get_promise = core_func
|
||||
.load_ae_obj_li__time_zone({
|
||||
api_cfg: $ae_api,
|
||||
only_priority: true,
|
||||
log_lvl: log_lvl
|
||||
})
|
||||
.then(function (lu_time_zone_li_get_result) {
|
||||
/* We need to save the time zone list to localStore */
|
||||
if (lu_time_zone_li_get_result) {
|
||||
lu_time_zone_list = lu_time_zone_li_get_result;
|
||||
localStorage.setItem(
|
||||
'lu_time_zone_list',
|
||||
JSON.stringify(lu_time_zone_li_get_result)
|
||||
);
|
||||
if (log_lvl) {
|
||||
console.log(`Time zone list:`, lu_time_zone_list);
|
||||
}
|
||||
} else {
|
||||
console.log(`No time zones returned!`);
|
||||
// $ae_loc.lu_time_zone_list = [];
|
||||
}
|
||||
|
||||
if (lu_time_zone_li_get_result) {
|
||||
lu_time_zone_list = lu_time_zone_li_get_result;
|
||||
console.log(`Time zone list:`, lu_time_zone_list);
|
||||
console.log(lu_time_zone_list[0]);
|
||||
console.log(lu_time_zone_list[10]);
|
||||
} else {
|
||||
console.log(`No time zones returned!`);
|
||||
lu_time_zone_list = [];
|
||||
}
|
||||
})
|
||||
.catch(function (error: any) {
|
||||
console.log('No results returned or failed.', error);
|
||||
});
|
||||
}
|
||||
// Trigger background IDB refresh if stale/empty; liveQuery reacts automatically
|
||||
core_func.load_ae_obj_li__time_zone({ api_cfg: $ae_api, log_lvl });
|
||||
});
|
||||
|
||||
function prevent_default<T extends Event>(fn: (event: T) => void) {
|
||||
@@ -873,7 +840,7 @@
|
||||
<fieldset class="flex_row flex_gap_md flex_justify_around">
|
||||
<label for="original_timezone"
|
||||
>Original Timezone
|
||||
{#if lu_time_zone_list}
|
||||
{#if ($lq__lu_time_zone ?? []).length}
|
||||
<select
|
||||
id="original_timezone"
|
||||
name="original_timezone"
|
||||
@@ -886,7 +853,7 @@
|
||||
title="Select the original timezone"
|
||||
>
|
||||
<option value="">-- None --</option>
|
||||
{#each lu_time_zone_list as lu_timezone (lu_timezone.name)}
|
||||
{#each ($lq__lu_time_zone ?? []) as lu_timezone (lu_timezone.name)}
|
||||
<option value={lu_timezone.name}>
|
||||
{lu_timezone.name}
|
||||
</option>
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
import type { key_val } from '$lib/stores/ae_stores';
|
||||
import { ae_util } from '$lib/ae_utils/ae_utils';
|
||||
import { core_func } from '$lib/ae_core/ae_core_functions';
|
||||
import { liveQuery } from 'dexie';
|
||||
import { db_lookups } from '$lib/ae_core/db_lookups';
|
||||
import {
|
||||
ae_snip,
|
||||
ae_loc,
|
||||
@@ -44,56 +46,21 @@
|
||||
let notes_changed = $state(false);
|
||||
let disable_submit_btn = true;
|
||||
|
||||
let lu_time_zone_list: any = $state(
|
||||
localStorage.getItem('lu_time_zone_list')
|
||||
? JSON.parse(localStorage.getItem('lu_time_zone_list') as string)
|
||||
: []
|
||||
// Timezone lookup — reactive IDB query; background refresh handled by liveQuery + TTL
|
||||
// Sort: sort DESC (higher = first, NULL=0 last), then name ASC — matches Aether backend convention.
|
||||
const lq__lu_time_zone = liveQuery(() =>
|
||||
db_lookups.lu_time_zone.toArray().then(arr =>
|
||||
arr.sort((a, b) => {
|
||||
const s_diff = Number(b['sort'] ?? 0) - Number(a['sort'] ?? 0);
|
||||
if (s_diff !== 0) return s_diff;
|
||||
return (a.name ?? '').localeCompare(b.name ?? '');
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
onMount(() => {
|
||||
$ae_loc.lu_time_zone_list = [];
|
||||
// $ae_loc.lu_time_zone_list = [];
|
||||
// lu_time_zone_list = [];
|
||||
if (lu_time_zone_list && lu_time_zone_list.length > 0) {
|
||||
// console.log('Already have time zone list!', lu_time_zone_list);
|
||||
} else {
|
||||
console.log('No time zone list');
|
||||
|
||||
let lu_time_zone_li_get_promise = core_func
|
||||
.load_ae_obj_li__time_zone({
|
||||
api_cfg: $ae_api,
|
||||
only_priority: true,
|
||||
log_lvl: log_lvl
|
||||
})
|
||||
.then(function (lu_time_zone_li_get_result) {
|
||||
/* We need to save the time zone list to localStore */
|
||||
if (lu_time_zone_li_get_result) {
|
||||
lu_time_zone_list = lu_time_zone_li_get_result;
|
||||
localStorage.setItem(
|
||||
'lu_time_zone_list',
|
||||
JSON.stringify(lu_time_zone_li_get_result)
|
||||
);
|
||||
if (log_lvl) {
|
||||
console.log(`Time zone list:`, lu_time_zone_list);
|
||||
}
|
||||
} else {
|
||||
console.log(`No time zones returned!`);
|
||||
// $ae_loc.lu_time_zone_list = [];
|
||||
}
|
||||
|
||||
if (lu_time_zone_li_get_result) {
|
||||
lu_time_zone_list = lu_time_zone_li_get_result;
|
||||
console.log(`Time zone list:`, lu_time_zone_list);
|
||||
console.log(lu_time_zone_list[0]);
|
||||
console.log(lu_time_zone_list[10]);
|
||||
} else {
|
||||
console.log(`No time zones returned!`);
|
||||
lu_time_zone_list = [];
|
||||
}
|
||||
})
|
||||
.catch(function (error: any) {
|
||||
console.log('No results returned or failed.', error);
|
||||
});
|
||||
}
|
||||
// Trigger background IDB refresh if stale/empty; liveQuery reacts automatically
|
||||
core_func.load_ae_obj_li__time_zone({ api_cfg: $ae_api, log_lvl });
|
||||
});
|
||||
|
||||
function prevent_default<T extends Event>(fn: (event: T) => void) {
|
||||
@@ -406,7 +373,7 @@
|
||||
<fieldset class="flex_row flex_gap_md flex_justify_around">
|
||||
<label for="original_timezone"
|
||||
>Original Timezone
|
||||
{#if lu_time_zone_list}
|
||||
{#if ($lq__lu_time_zone ?? []).length}
|
||||
<select
|
||||
name="original_timezone"
|
||||
id="original_timezone"
|
||||
@@ -418,7 +385,7 @@
|
||||
title="Select the original timezone"
|
||||
>
|
||||
<option value="">-- None --</option>
|
||||
{#each lu_time_zone_list as lu_timezone (lu_timezone.name)}
|
||||
{#each ($lq__lu_time_zone ?? []) as lu_timezone (lu_timezone.name)}
|
||||
<option value={lu_timezone.name}>
|
||||
{lu_timezone.name}
|
||||
</option>
|
||||
|
||||
@@ -190,14 +190,35 @@
|
||||
// Lookup lists — reactive IDB queries (SWR via db_lookups + liveQuery)
|
||||
// Data persists in IndexedDB with a 24h TTL; onMount triggers a background
|
||||
// refresh if IDB is empty or stale. No localStorage or $ae_loc involved.
|
||||
// Note: orderBy() requires a declared Dexie index. For fields not in the schema index,
|
||||
// use toArray() + in-memory sort instead to avoid a silent liveQuery error.
|
||||
// Sort convention matches the Aether backend: sort DESC (higher = first, NULL=0 last), then name ASC.
|
||||
const lq__lu_country = liveQuery(() =>
|
||||
db_lookups.lu_country.orderBy('english_short_name').toArray()
|
||||
db_lookups.lu_country.toArray().then(arr =>
|
||||
arr.sort((a, b) => {
|
||||
const s_diff = Number(b['sort'] ?? 0) - Number(a['sort'] ?? 0);
|
||||
if (s_diff !== 0) return s_diff;
|
||||
return (a.english_short_name ?? a.name ?? '').localeCompare(b.english_short_name ?? b.name ?? '');
|
||||
})
|
||||
)
|
||||
);
|
||||
const lq__lu_country_subdivision = liveQuery(() =>
|
||||
db_lookups.lu_country_subdivision.orderBy('name').toArray()
|
||||
db_lookups.lu_country_subdivision.toArray().then(arr =>
|
||||
arr.sort((a, b) => {
|
||||
const s_diff = Number(b['sort'] ?? 0) - Number(a['sort'] ?? 0);
|
||||
if (s_diff !== 0) return s_diff;
|
||||
return (a.name ?? '').localeCompare(b.name ?? '');
|
||||
})
|
||||
)
|
||||
);
|
||||
const lq__lu_time_zone = liveQuery(() =>
|
||||
db_lookups.lu_time_zone.orderBy('name').toArray()
|
||||
db_lookups.lu_time_zone.toArray().then(arr =>
|
||||
arr.sort((a, b) => {
|
||||
const s_diff = Number(b['sort'] ?? 0) - Number(a['sort'] ?? 0);
|
||||
if (s_diff !== 0) return s_diff;
|
||||
return (a.name ?? '').localeCompare(b.name ?? '');
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
onMount(() => {
|
||||
|
||||
Reference in New Issue
Block a user