diff --git a/GEMINI.md b/GEMINI.md index 9cb7b601..1ddc7de6 100644 --- a/GEMINI.md +++ b/GEMINI.md @@ -42,20 +42,20 @@ The following directories are ignored for various operations (e.g., search, file This project uses Svelte v5 with runes enabled. This introduces significant differences from Svelte v4. It is critical to adhere to v5 conventions to avoid bugs. -- **Reactivity:** State is managed with `$state` and `$derived`. Props can be made two-way bindable with `$bindable`. Avoid direct mutation of props. -- **Event Handling:** - - DOM events still use the `on:eventname` directive (e.g., `on:click`, `on:input`). - - Component events are dispatched with `createEventDispatcher` and listened to with `on:eventname`. - - For two-way binding on component props, use `bind:propName`. -- **Stores and `liveQuery`:** - - To access the value of a store in Svelte v5, you must use the `$store_name` syntax (e.g., `$ae_api`). - - Dexie `liveQuery` returns an observable. To use it in a component, you must subscribe to it within `onMount` to avoid SSR errors. The value from the subscription should then be assigned to a `$state` variable. -- **Migration Guide:** For a comprehensive overview of the changes, refer to the official [Svelte 5 Migration Guide](https://svelte.dev/docs/svelte/v5-migration-guide). +- **Reactivity:** State is managed with `$state` and `$derived`. Props can be made two-way bindable with `$bindable`. Avoid direct mutation of props. +- **Event Handling:** + - DOM events still use the `on:eventname` directive (e.g., `on:click`, `on:input`). + - Component events are dispatched with `createEventDispatcher` and listened to with `on:eventname`. + - For two-way binding on component props, use `bind:propName`. +- **Stores and `liveQuery`:** + - To access the value of a store in Svelte v5, you must use the `$store_name` syntax (e.g., `$ae_api`). + - Dexie `liveQuery` returns an observable. To use it in a component, you must subscribe to it within `onMount` to avoid SSR errors. The value from the subscription should then be assigned to a `$state` variable. +- **Migration Guide:** For a comprehensive overview of the changes, refer to the official [Svelte 5 Migration Guide](https://svelte.dev/docs/svelte/v5-migration-guide). ### ID Convention: `id` vs. `id_random` -- **Always use `id_random`:** The API returns both a numeric `id` and a string-based `[obj_type]_id_random`. For all frontend operations (routing, data fetching, local storage), you **must** use the `_id_random` string. -- **Local Storage:** When saving an object to the local IndexedDB (Dexie), the `id_random` value should be aliased to both `id` (as the primary key) and `[obj_type]_id`. This ensures consistency with Dexie's expectations and the rest of the application's data access patterns. +- **Always use `id_random`:** The API returns both a numeric `id` and a string-based `[obj_type]_id_random`. For all frontend operations (routing, data fetching, local storage), you **must** use the `_id_random` string. +- **Local Storage:** When saving an object to the local IndexedDB (Dexie), the `id_random` value should be aliased to both `id` (as the primary key) and `[obj_type]_id`. This ensures consistency with Dexie's expectations and the rest of the application's data access patterns. --- @@ -128,10 +128,10 @@ A new event settings page was created at `/events/[event_id]/settings` to provid **Key features:** -- **Form-Based UI:** Instead of raw JSON editing, the page uses form-based components for editing event properties. This includes basic event fields (name, code, dates, etc.) and the JSON configuration fields (`cfg_json`, `mod_pres_mgmt_json`, `mod_badges_json`, `mod_abstracts_json`). -- **Collapsible Sections:** Each configuration section is wrapped in a `
` element, allowing them to be collapsed and expanded for better organization. -- **View Toggling:** For the JSON configuration fields, a toggle switch allows the user to switch between the form-based UI and a raw JSON editor (using CodeMirror), providing flexibility for both simple and advanced editing. -- **Svelte 5 Reactivity:** The components were built using Svelte 5's `bindable` props to ensure proper two-way data binding between the parent page and the child form components. This corrected an issue where changes in the child components were not being reflected in the parent's state. +- **Form-Based UI:** Instead of raw JSON editing, the page uses form-based components for editing event properties. This includes basic event fields (name, code, dates, etc.) and the JSON configuration fields (`cfg_json`, `mod_pres_mgmt_json`, `mod_badges_json`, `mod_abstracts_json`). +- **Collapsible Sections:** Each configuration section is wrapped in a `
` element, allowing them to be collapsed and expanded for better organization. +- **View Toggling:** For the JSON configuration fields, a toggle switch allows the user to switch between the form-based UI and a raw JSON editor (using CodeMirror), providing flexibility for both simple and advanced editing. +- **Svelte 5 Reactivity:** The components were built using Svelte 5's `bindable` props to ensure proper two-way data binding between the parent page and the child form components. This corrected an issue where changes in the child components were not being reflected in the parent's state. ### API Payload Cleaning (2025-11-19) @@ -139,12 +139,12 @@ To address issues with the Aether API's strict handling of `POST` and `PATCH` re **Key aspects of the changes:** -- **Svelte 5 Event Handlers:** Corrected the use of `on:click` to `onclick` in the event settings components to align with Svelte 5 conventions. -- **Payload Cleaning:** - - The `update_ae_obj__event` function in `src/lib/ae_events/ae_events__event.ts` was modified to remove read-only fields (`id`, `event_id`, `created_on`, `updated_on`, etc.) from the payload before sending it to the API. - - The function now also correctly renames `account_id` to `account_id_random` to match the API's expectations. -- **Editable Fields Whitelist:** - - A new file, `src/lib/ae_events/ae_events__event.editable_fields.ts`, was created to define a whitelist of fields that are allowed to be sent in `POST` and `PATCH` requests for an event. - - The `create_ae_obj__event` and `update_ae_obj__event` functions now use this whitelist to filter the `data_kv` object, ensuring only allowed fields are sent to the API. This provides a more maintainable and less error-prone way to manage which fields are sent to the API. -- **Component Cleanup:** The temporary pre-cleaning logic from the `handle_save` function in `src/routes/events/[event_id]/settings/+page.svelte` has been removed, as the filtering is now handled centrally in `ae_events__event.ts`. -- **Future Work:** This pattern of using a whitelist for editable fields will be applied to all other Aether object types to ensure consistent and correct API interactions across the application. +- **Svelte 5 Event Handlers:** Corrected the use of `on:click` to `onclick` in the event settings components to align with Svelte 5 conventions. +- **Payload Cleaning:** + - The `update_ae_obj__event` function in `src/lib/ae_events/ae_events__event.ts` was modified to remove read-only fields (`id`, `event_id`, `created_on`, `updated_on`, etc.) from the payload before sending it to the API. + - The function now also correctly renames `account_id` to `account_id_random` to match the API's expectations. +- **Editable Fields Whitelist:** + - A new file, `src/lib/ae_events/ae_events__event.editable_fields.ts`, was created to define a whitelist of fields that are allowed to be sent in `POST` and `PATCH` requests for an event. + - The `create_ae_obj__event` and `update_ae_obj__event` functions now use this whitelist to filter the `data_kv` object, ensuring only allowed fields are sent to the API. This provides a more maintainable and less error-prone way to manage which fields are sent to the API. +- **Component Cleanup:** The temporary pre-cleaning logic from the `handle_save` function in `src/routes/events/[event_id]/settings/+page.svelte` has been removed, as the filtering is now handled centrally in `ae_events__event.ts`. +- **Future Work:** This pattern of using a whitelist for editable fields will be applied to all other Aether object types to ensure consistent and correct API interactions across the application. diff --git a/src/lib/ae_core/ae_comp__hosted_files_clip_video_v1.svelte b/src/lib/ae_core/ae_comp__hosted_files_clip_video_v1.svelte index c1475e9b..ba8f5daa 100644 --- a/src/lib/ae_core/ae_comp__hosted_files_clip_video_v1.svelte +++ b/src/lib/ae_core/ae_comp__hosted_files_clip_video_v1.svelte @@ -1,7 +1,6 @@
diff --git a/src/lib/elements/element_data_store.svelte b/src/lib/elements/element_data_store.svelte index 7e84dff8..e610f7ab 100644 --- a/src/lib/elements/element_data_store.svelte +++ b/src/lib/elements/element_data_store.svelte @@ -8,17 +8,10 @@ import { ae_util } from '$lib/ae_utils/ae_utils'; import type { key_val } from '$lib/stores/ae_stores'; - console.log( `ae_e_data_store ${ds_code} for_type=${for_type} for_id=${for_id} account_id=${$ae_loc.account_id}` ); - - - - - - let ae_promises: key_val = {}; // Promise; let ds_get_results: Promise | key_val = $state(); let ds_loading_status: string = 'starting...'; @@ -178,7 +171,6 @@ } }); - async function load_data_store({ code, type = 'text', diff --git a/src/lib/elements/element_data_store_v2.svelte b/src/lib/elements/element_data_store_v2.svelte index fc1b7917..24fa1434 100644 --- a/src/lib/elements/element_data_store_v2.svelte +++ b/src/lib/elements/element_data_store_v2.svelte @@ -19,11 +19,6 @@ }); // export let store: string = 'local'; - - - - - let ae_promises: key_val = {}; // let ae_tmp: key_val = {}; @@ -168,7 +163,6 @@ }, random_ms); } - async function load_data_store({ code, type = 'text', @@ -774,23 +768,21 @@ {#snippet footer()} - -
- -
- - {/snippet} + class="btn btn-sm preset-tonal-warning hover:preset-tonal-warning border border-warning-500" + > + + Close + +
+ {/snippet} diff --git a/src/lib/elements/element_input_file.svelte b/src/lib/elements/element_input_file.svelte index 97198507..f4551226 100644 --- a/src/lib/elements/element_input_file.svelte +++ b/src/lib/elements/element_input_file.svelte @@ -9,9 +9,6 @@ import { check_hosted_file_obj_w_hash } from '$lib/ae_core/core__check_hosted_file_obj_w_hash'; import { ae_loc, ae_sess, ae_api, ae_trig, slct, slct_trigger } from '$lib/stores/ae_stores'; - - - const dispatch = createEventDispatcher(); interface Props { @@ -53,7 +50,6 @@ console.log('** Element Mounted: ** Element Input File'); }); - async function process_file_list(file_list) { console.log('*** process_file_list() ***'); diff --git a/src/lib/elements/element_input_files_tbl.svelte b/src/lib/elements/element_input_files_tbl.svelte index 3cdfaedc..0622f74a 100644 --- a/src/lib/elements/element_input_files_tbl.svelte +++ b/src/lib/elements/element_input_files_tbl.svelte @@ -9,9 +9,6 @@ import { check_hosted_file_obj_w_hash } from '$lib/ae_core/core__check_hosted_file_obj_w_hash'; import { ae_loc, ae_sess, ae_api, ae_trig, slct, slct_trigger } from '$lib/stores/ae_stores'; - - - interface Props { // export let element_id = 'svelte_input_file_element'; container_class_li?: string[]; @@ -43,7 +40,6 @@ console.log('** Element Mounted: ** Element Input File'); }); - async function process_file_list(file_list) { console.log('*** process_file_list() ***'); diff --git a/src/lib/elements/element_input_v2.svelte b/src/lib/elements/element_input_v2.svelte index f0a2673a..4eac138c 100644 --- a/src/lib/elements/element_input_v2.svelte +++ b/src/lib/elements/element_input_v2.svelte @@ -7,19 +7,11 @@ // import Select_element_lu from './element_select_lu.svelte'; - - - - - - console.log(`Input name=${name} value=${value}`); - + console.log('Original Value', original_value); console.log('Data Type:', data_type); - - let set_input_type = $state((node) => { node.type = 'text'; }); @@ -33,37 +25,20 @@ console.log(`Input name=${name} value=${value} type=${type}`); - /* *** END *** Core input settings */ /* *** BEGIN *** Container content, layout, and behavior */ - - - - - - - - - - - - console.log(`Input input_mode=${input_mode}`); /* *** END *** Container content, layout, and behavior */ /* *** BEGIN *** Input type specific */ - - - if (type == 'textarea') { console.log(`Input textarea size=${size} rows=${rows} cols=${cols}`); } - interface Props { /* *** BEGIN *** Core input settings */ id_random?: string; // OSIT Aether specific diff --git a/src/lib/elements/element_obj_tbl_row.svelte b/src/lib/elements/element_obj_tbl_row.svelte index 90b4ee06..fb296153 100644 --- a/src/lib/elements/element_obj_tbl_row.svelte +++ b/src/lib/elements/element_obj_tbl_row.svelte @@ -19,7 +19,11 @@ obj?: any; } - let { row_header = false, primary_obj_li_type = $bindable(slct_obj_li_type), obj = null }: Props = $props(); + let { + row_header = false, + primary_obj_li_type = $bindable(slct_obj_li_type), + obj = null + }: Props = $props(); console.log(obj); console.log(typeof obj); diff --git a/src/lib/elements/element_sql_qry.svelte b/src/lib/elements/element_sql_qry.svelte index a146b863..c53fa0a4 100644 --- a/src/lib/elements/element_sql_qry.svelte +++ b/src/lib/elements/element_sql_qry.svelte @@ -14,8 +14,6 @@ // *** Import Aether module components - - interface Props { // *** Export/Exposed variables and functions for component api_cfg: any; diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 49d8e971..f3f37192 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -1,5 +1,4 @@

Event Settings

{#if event_obj} -
-
- Basic Info -
- handle_save('basic_fields', e.detail)} - /> -
-
+
+
+ Basic Info +
+ handle_save('basic_fields', e.detail)} + /> +
+
-
- General Config (cfg_json) -
-
- - -
- {#if cfg_json_view === 'form'} - handle_save('cfg_json', e.detail)} - /> - {:else} - { - event_obj.cfg_json = e.detail; - }} - /> - - {/if} -
-
+
+ General Config (cfg_json) +
+
+ + +
+ {#if cfg_json_view === 'form'} + handle_save('cfg_json', e.detail)} + /> + {:else} + { + event_obj.cfg_json = e.detail; + }} + /> + + {/if} +
+
-
- Presentation Management (mod_pres_mgmt_json) -
-
- - -
- {#if pres_mgmt_json_view === 'form'} - handle_save('mod_pres_mgmt_json', e.detail)} - /> - {:else} - { - event_obj.mod_pres_mgmt_json = e.detail; - }} - /> - - {/if} -
-
+
+ Presentation Management (mod_pres_mgmt_json) +
+
+ + +
+ {#if pres_mgmt_json_view === 'form'} + handle_save('mod_pres_mgmt_json', e.detail)} + /> + {:else} + { + event_obj.mod_pres_mgmt_json = e.detail; + }} + /> + + {/if} +
+
-
- Badges (mod_badges_json) -
-
- - -
- {#if badges_json_view === 'form'} - handle_save('mod_badges_json', e.detail)} - /> - {:else} - { - event_obj.mod_badges_json = e.detail; - }} - /> - - {/if} -
-
+
+ Badges (mod_badges_json) +
+
+ + +
+ {#if badges_json_view === 'form'} + handle_save('mod_badges_json', e.detail)} + /> + {:else} + { + event_obj.mod_badges_json = e.detail; + }} + /> + + {/if} +
+
-
- Abstracts (mod_abstracts_json) -
-
- - -
- {#if abstracts_json_view === 'form'} - handle_save('mod_abstracts_json', e.detail)} - /> - {:else} - { - event_obj.mod_abstracts_json = e.detail; - }} - /> - - {/if} -
-
+
+ Abstracts (mod_abstracts_json) +
+
+ + +
+ {#if abstracts_json_view === 'form'} + handle_save('mod_abstracts_json', e.detail)} + /> + {:else} + { + event_obj.mod_abstracts_json = e.detail; + }} + /> + + {/if} +
+
-
- Exhibits (mod_exhibits_json) -
- { - event_obj.mod_exhibits_json = e.detail; - }} - /> - -
-
+
+ Exhibits (mod_exhibits_json) +
+ { + event_obj.mod_exhibits_json = e.detail; + }} + /> + +
+
-
- Meetings (mod_meetings_json) -
- { - event_obj.mod_meetings_json = e.detail; - }} - /> - -
-
-
+
+ Meetings (mod_meetings_json) +
+ { + event_obj.mod_meetings_json = e.detail; + }} + /> + +
+
+
{:else} -

Loading event data...

+

Loading event data...

{/if} diff --git a/src/routes/events/[event_id]/settings/ae_comp__event_settings_abstracts_form.svelte b/src/routes/events/[event_id]/settings/ae_comp__event_settings_abstracts_form.svelte index 6bedc639..22298003 100644 --- a/src/routes/events/[event_id]/settings/ae_comp__event_settings_abstracts_form.svelte +++ b/src/routes/events/[event_id]/settings/ae_comp__event_settings_abstracts_form.svelte @@ -1,99 +1,103 @@
-
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
- +
diff --git a/src/routes/events/[event_id]/settings/ae_comp__event_settings_badges_form.svelte b/src/routes/events/[event_id]/settings/ae_comp__event_settings_badges_form.svelte index 3510f7a8..fdc31979 100644 --- a/src/routes/events/[event_id]/settings/ae_comp__event_settings_badges_form.svelte +++ b/src/routes/events/[event_id]/settings/ae_comp__event_settings_badges_form.svelte @@ -1,90 +1,98 @@
-
-
- -
-
- -
-
- -
-
- -
-
- -
-
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
-
-
- -
-
- -
-
- -
-
+
+
+ +
+
+ +
+
+ +
+
- +
diff --git a/src/routes/events/[event_id]/settings/ae_comp__event_settings_basic_form.svelte b/src/routes/events/[event_id]/settings/ae_comp__event_settings_basic_form.svelte index a7299672..4cd05402 100644 --- a/src/routes/events/[event_id]/settings/ae_comp__event_settings_basic_form.svelte +++ b/src/routes/events/[event_id]/settings/ae_comp__event_settings_basic_form.svelte @@ -1,74 +1,74 @@
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
- +
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
diff --git a/src/routes/events/[event_id]/settings/ae_comp__event_settings_form.svelte b/src/routes/events/[event_id]/settings/ae_comp__event_settings_form.svelte index b6c14f31..cba3d821 100644 --- a/src/routes/events/[event_id]/settings/ae_comp__event_settings_form.svelte +++ b/src/routes/events/[event_id]/settings/ae_comp__event_settings_form.svelte @@ -1,32 +1,32 @@
-
- -
-
- -
- +
+ +
+
+ +
+
diff --git a/src/routes/events/[event_id]/settings/ae_comp__event_settings_pres_mgmt_form.svelte b/src/routes/events/[event_id]/settings/ae_comp__event_settings_pres_mgmt_form.svelte index b2a2abea..bfd2fc73 100644 --- a/src/routes/events/[event_id]/settings/ae_comp__event_settings_pres_mgmt_form.svelte +++ b/src/routes/events/[event_id]/settings/ae_comp__event_settings_pres_mgmt_form.svelte @@ -1,138 +1,146 @@
-
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
-
-
- -
-
- -
-
- -
-
+
+
+ +
+
+ +
+
+ +
+
- +
diff --git a/src/routes/events/ae_comp__events_menu_nav.svelte b/src/routes/events/ae_comp__events_menu_nav.svelte index c0f5df9c..6db94e8e 100644 --- a/src/routes/events/ae_comp__events_menu_nav.svelte +++ b/src/routes/events/ae_comp__events_menu_nav.svelte @@ -8,11 +8,7 @@ slct, slct_trigger } from '$lib/stores/ae_stores'; - - - - interface Props { // import { events_loc, events_sess, events_slct, events_trigger, events_trig_kv } from '$lib/stores/ae_events_stores'; hide?: boolean; diff --git a/src/routes/events_badges/+layout.svelte b/src/routes/events_badges/+layout.svelte index d3f4bf98..51c54d9d 100644 --- a/src/routes/events_badges/+layout.svelte +++ b/src/routes/events_badges/+layout.svelte @@ -1,6 +1,4 @@
diff --git a/src/routes/events_leads/exhibit/[slug]/leads_view_lead.svelte b/src/routes/events_leads/exhibit/[slug]/leads_view_lead.svelte index 66173096..73001c8f 100644 --- a/src/routes/events_leads/exhibit/[slug]/leads_view_lead.svelte +++ b/src/routes/events_leads/exhibit/[slug]/leads_view_lead.svelte @@ -25,11 +25,13 @@ // These will likely be used for patch/update triggers. Maybe delete? let ae_triggers: key_val = $state({}); - let event_exhibit_obj = $derived(liveQuery(() => db_events.exhibit.get($events_slct.exhibit_id))); + let event_exhibit_obj = $derived( + liveQuery(() => db_events.exhibit.get($events_slct.exhibit_id)) + ); - let event_exhibit_tracking_obj = $derived(liveQuery(() => - db_events.exhibit_tracking.get($events_slct.exhibit_tracking_id) - )); + let event_exhibit_tracking_obj = $derived( + liveQuery(() => db_events.exhibit_tracking.get($events_slct.exhibit_tracking_id)) + ); // Quickly reload the data for this AE object from the API/DB run(() => { diff --git a/src/routes/idaa/(idaa)/bb/ae_idaa_comp__post_obj_li.svelte b/src/routes/idaa/(idaa)/bb/ae_idaa_comp__post_obj_li.svelte index 46e2a349..9f81b3bf 100644 --- a/src/routes/idaa/(idaa)/bb/ae_idaa_comp__post_obj_li.svelte +++ b/src/routes/idaa/(idaa)/bb/ae_idaa_comp__post_obj_li.svelte @@ -1,5 +1,4 @@