diff --git a/src/lib/ae_api/api_get__lookup_v3.ts b/src/lib/ae_api/api_get__lookup_v3.ts index 692ad996..5e4a9dda 100644 --- a/src/lib/ae_api/api_get__lookup_v3.ts +++ b/src/lib/ae_api/api_get__lookup_v3.ts @@ -16,6 +16,9 @@ export async function get_ae_lookup_li_v3({ for_id, include_disabled = false, only_priority = false, + order_by_li = null, + limit = null, + offset = null, params = {}, headers = {}, log_lvl = 0 @@ -27,6 +30,9 @@ export async function get_ae_lookup_li_v3({ for_id?: string; include_disabled?: boolean; only_priority?: boolean; + order_by_li?: Record | null; + limit?: number | null; + offset?: number | null; params?: key_val; headers?: Record; log_lvl?: number; @@ -43,6 +49,9 @@ export async function get_ae_lookup_li_v3({ if (for_id) params['for_id'] = for_id; if (include_disabled) params['include_disabled'] = true; if (only_priority) params['only_priority'] = true; + if (order_by_li) params['order_by_li'] = JSON.stringify(order_by_li); + if (limit != null) params['limit'] = limit; + if (offset != null) params['offset'] = offset; // Lookup data is often global; ensure account context is handled if needed, // but GUIDE says it uses site Whitelist Policy. diff --git a/src/lib/ae_core/core__time_zones.ts b/src/lib/ae_core/core__time_zones.ts index e205e279..945d720d 100644 --- a/src/lib/ae_core/core__time_zones.ts +++ b/src/lib/ae_core/core__time_zones.ts @@ -48,6 +48,7 @@ export async function load_ae_obj_li__time_zone({ hidden: hidden, limit: limit, offset: offset, + order_by_li: order_by_li, params: params, only_priority: only_priority, log_lvl: log_lvl diff --git a/src/lib/api/api.ts b/src/lib/api/api.ts index 4848e03e..c55ac23c 100644 --- a/src/lib/api/api.ts +++ b/src/lib/api/api.ts @@ -80,6 +80,9 @@ export const get_ae_obj_li_for_lu = async function get_ae_obj_li_for_lu({ lu_type: for_lu_type, include_disabled: enabled === 'all', only_priority: only_priority, + order_by_li: order_by_li ?? undefined, + limit: limit ?? undefined, + offset: offset ?? undefined, params, headers: merged_headers, log_lvl diff --git a/src/routes/idaa/(idaa)/recovery_meetings/[event_id]/+page.svelte b/src/routes/idaa/(idaa)/recovery_meetings/[event_id]/+page.svelte index 60e8069a..281dff28 100644 --- a/src/routes/idaa/(idaa)/recovery_meetings/[event_id]/+page.svelte +++ b/src/routes/idaa/(idaa)/recovery_meetings/[event_id]/+page.svelte @@ -63,8 +63,10 @@ } let results = await db_events.event.get($idaa_slct?.event_id ?? ''); // null or undefined does not reset things like '' does - // Check if results are different than the current $idaa_slct.event_obj - if ($idaa_slct.event_obj && results) { + // Check if results are different than the current $idaa_slct.event_obj. + // Skip the sync while the edit form is open — overwriting would discard + // the user's in-progress changes (e.g. weekday chips, pattern, times). + if ($idaa_slct.event_obj && results && !$idaa_sess.recovery_meetings.edit__event_obj) { if ( JSON.stringify($idaa_slct.event_obj) !== JSON.stringify(results) diff --git a/src/routes/idaa/(idaa)/recovery_meetings/ae_idaa_comp__event_obj_id_edit.svelte b/src/routes/idaa/(idaa)/recovery_meetings/ae_idaa_comp__event_obj_id_edit.svelte index 1bbc11c3..35bfacf0 100644 --- a/src/routes/idaa/(idaa)/recovery_meetings/ae_idaa_comp__event_obj_id_edit.svelte +++ b/src/routes/idaa/(idaa)/recovery_meetings/ae_idaa_comp__event_obj_id_edit.svelte @@ -12,7 +12,7 @@ }: Props = $props(); // *** Import Svelte specific - import { onMount } from 'svelte'; + import { onMount, untrack } from 'svelte'; import { fade } from 'svelte/transition'; import { browser } from '$app/environment'; import { goto } from '$app/navigation'; @@ -72,6 +72,33 @@ let disable_submit_btn = $state(true); + // Weekday chip state — local $state is required because Svelte 5 does not reliably + // propagate reactivity through dynamic bracket notation ($store[dynamicKey]) on + // writable stores. Direct property access (.physical, .virtual) works fine; loop-variable + // bracket access does not trigger class re-renders. $state is deep-reactive and does. + const WEEKDAY_KEYS = [ + 'weekday_sunday', 'weekday_monday', 'weekday_tuesday', 'weekday_wednesday', + 'weekday_thursday', 'weekday_friday', 'weekday_saturday' + ] as const; + let weekdays = $state>({ + weekday_sunday: false, weekday_monday: false, weekday_tuesday: false, + weekday_wednesday: false, weekday_thursday: false, weekday_friday: false, + weekday_saturday: false + }); + // Seed once from liveQuery when data first arrives. Plain JS flag (not $state) so + // it doesn't cause the effect to re-run after the one-time init. + let weekdays_initialized = false; + $effect(() => { + if (!weekdays_initialized && $lq__event_obj?.event_id) { + untrack(() => { + for (const key of WEEKDAY_KEYS) { + weekdays[key] = !!$lq__event_obj[key]; + } + weekdays_initialized = true; + }); + } + }); + // Contact 1 is locked by default on existing meetings for non-trusted users. // This prevents accidental override of the meeting owner's contact info. // Trusted+ users see no lock UI; new meetings start unlocked. @@ -406,21 +433,21 @@ event_do['recurring'] = true; event_do['recurring_pattern'] = event_meeting_fd.recurring_pattern; - // !! converts to boolean based on truthiness - event_do['weekday_sunday'] = !!event_meeting_fd.weekday_sunday; - event_do['weekday_monday'] = !!event_meeting_fd.weekday_monday; - event_do['weekday_tuesday'] = !!event_meeting_fd.weekday_tuesday; - event_do['weekday_wednesday'] = !!event_meeting_fd.weekday_wednesday; - event_do['weekday_thursday'] = !!event_meeting_fd.weekday_thursday; - event_do['weekday_friday'] = !!event_meeting_fd.weekday_friday; - event_do['weekday_saturday'] = !!event_meeting_fd.weekday_saturday; + // Read weekdays from local $state (not FormData) — bind:checked with dynamic bracket + // notation in {#each} is unreliable in Svelte 5; explicit onchange handlers update + // the weekdays $state object directly, so read from there instead. + event_do['weekday_sunday'] = weekdays.weekday_sunday; + event_do['weekday_monday'] = weekdays.weekday_monday; + event_do['weekday_tuesday'] = weekdays.weekday_tuesday; + event_do['weekday_wednesday'] = weekdays.weekday_wednesday; + event_do['weekday_thursday'] = weekdays.weekday_thursday; + event_do['weekday_friday'] = weekdays.weekday_friday; + event_do['weekday_saturday'] = weekdays.weekday_saturday; - if (event_meeting_fd['recurring_start_time']) { - event_do['recurring_start_time'] = event_meeting_fd.recurring_start_time; - } - if (event_meeting_fd['recurring_end_time']) { - event_do['recurring_end_time'] = event_meeting_fd.recurring_end_time; - } + // Send null explicitly so the user can clear a time once set. + // An empty string from the time input means "no time" — map that to null. + event_do['recurring_start_time'] = event_meeting_fd.recurring_start_time || null; + event_do['recurring_end_time'] = event_meeting_fd.recurring_end_time || null; if (typeof recurring_text_new_html === 'string') { event_do['recurring_text'] = recurring_text_new_html; @@ -620,8 +647,10 @@ Copy and paste link: ${ }); } - // Track whether the form has unsaved changes relative to the original loaded object + // Track whether the form has unsaved changes relative to the original loaded object. + // weekdays is checked separately since it's a local $state, not part of $idaa_slct.event_obj. $effect(() => { + const weekdays_changed = WEEKDAY_KEYS.some(k => !!weekdays[k] !== !!orig_event_obj?.[k]); if (orig_event_obj === null || orig_event_obj === undefined) { obj_changed = false; } else if ( @@ -629,7 +658,8 @@ Copy and paste link: ${ orig_event_obj?.id && (JSON.stringify($idaa_slct.event_obj) !== JSON.stringify(orig_event_obj) || description_changed || - notes_changed) + notes_changed || + weekdays_changed) ) { obj_changed = true; } else if ( @@ -637,7 +667,8 @@ Copy and paste link: ${ orig_event_obj?.id && JSON.stringify($idaa_slct.event_obj) === JSON.stringify(orig_event_obj) && !description_changed && - !notes_changed + !notes_changed && + !weekdays_changed ) { obj_changed = false; } @@ -1365,13 +1396,14 @@ Copy and paste link: ${ Schedule - + @@ -1442,13 +1479,14 @@ Copy and paste link: ${ {/if} + @@ -1459,7 +1497,7 @@ Copy and paste link: ${ type="time" id="recurring_end_time" name="recurring_end_time" - value={$lq__event_obj?.recurring_end_time} + bind:value={$idaa_slct.event_obj.recurring_end_time} class="input preset-tonal-surface hover:preset-filled-surface-100-900 w-36" />