diff --git a/src/lib/ae_reports/reports_functions.ts b/src/lib/ae_reports/reports_functions.ts index 587bc9f5..11aea8af 100644 --- a/src/lib/ae_reports/reports_functions.ts +++ b/src/lib/ae_reports/reports_functions.ts @@ -38,7 +38,6 @@ export async function qry__jitsi_report({ // Step 1: Query all relevant activity logs from the API. const search_query = { or: [ - { field: 'name', op: 'eq', value: 'jitsi_meeting_stats_update' }, { field: 'name', op: 'eq', value: 'jitsi_meeting_event' }, { field: 'name', op: 'eq', value: 'jitsi_meeting_stats' } ], diff --git a/src/lib/elements/element_data_store_v3.svelte b/src/lib/elements/element_data_store_v3.svelte new file mode 100644 index 00000000..93364583 --- /dev/null +++ b/src/lib/elements/element_data_store_v3.svelte @@ -0,0 +1,430 @@ + + +
+ + {#if $lq__ds_obj} + {#if debug || $ae_loc.debug === 'debug'} + Debug is ON! +
+    ID: {$lq__ds_obj.id}
+    Code: {$lq__ds_obj.code}
+    Name: {$lq__ds_obj.name}
+    Type: {$lq__ds_obj.type}
+    Account: {$lq__ds_obj.account_id || 'Global / NULL'}
+    Created: {$lq__ds_obj.created_on}
+    Updated: {$lq__ds_obj.updated_on}
+            
+ +
+ {/if} + + +
{ e.preventDefault(); handle_submit_form(e); }}> + + +
+
+ + +
+ +
+ +
+ + Account Specific +
+
+
+ +
+ Content + +
+ +
+ Created on: {$lq__ds_obj.created_on} | Last Updated: {$lq__ds_obj.updated_on} +
+ + +
+ + +
+ + +
+
+
+
+ + {#if show_view} + {#if $lq__ds_obj.type === 'html' && $lq__ds_obj.html} + {@html $lq__ds_obj.html} + {:else if $lq__ds_obj.type === 'text' && $lq__ds_obj.text} +
{$lq__ds_obj.text}
+ {:else if $lq__ds_obj.type === 'sql' && $lq__ds_obj.text} + {#if debug}
SQL: {$lq__ds_obj.text}
{/if} + {/if} + {/if} + + {#if $ae_loc.edit_mode && ($ae_loc.manager_access || (show_edit_btn && $ae_loc.administrator_access))} + + {/if} + {:else if ds_loading_status === 'not found'} + + {#if $ae_loc.administrator_access || ($ae_loc.trusted_access && $ae_loc.edit_mode)} +
+ Data Store not found: {ds_code} +
+ {/if} + {/if} + + {#if ds_loading_status === 'loading'} +
+ +
+ {/if} +
diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 7d7c5f3e..87829f40 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -8,7 +8,7 @@ // import { PUBLIC_TESTING } from '$env/static/public'; // console.log(`AE Config - +page.svelte PUBLIC_TESTING:`, PUBLIC_TESTING); - import Element_data_store from '$lib/elements/element_data_store.svelte'; + import Element_data_store from '$lib/elements/element_data_store_v3.svelte'; // import { api } from '$lib/api'; import { ae_loc, ae_sess, ae_api, slct, slct_trigger } from '$lib/stores/ae_stores'; diff --git a/src/routes/core/people/[person_id]/+page.svelte b/src/routes/core/people/[person_id]/+page.svelte index 76577bde..58ba4ce1 100644 --- a/src/routes/core/people/[person_id]/+page.svelte +++ b/src/routes/core/people/[person_id]/+page.svelte @@ -8,7 +8,7 @@ import type { key_val } from '$lib/stores/ae_stores'; import { ae_util } from '$lib/ae_utils/ae_utils'; // import { api } from '$lib/api'; - import Element_data_store from '$lib/elements/element_data_store.svelte'; + import Element_data_store from '$lib/elements/element_data_store_v3.svelte'; import { liveQuery } from 'dexie'; // import { core_func } from '$lib/ae_core_functions'; diff --git a/src/routes/events/+layout.svelte b/src/routes/events/+layout.svelte index f4489521..b3f7096e 100644 --- a/src/routes/events/+layout.svelte +++ b/src/routes/events/+layout.svelte @@ -22,7 +22,7 @@ // *** Import Aether specific variables and functions import type { key_val } from '$lib/stores/ae_stores'; import { ae_loc, ae_sess, ae_api, slct } from '$lib/stores/ae_stores'; - import Element_data_store from '$lib/elements/element_data_store.svelte'; + import Element_data_store from '$lib/elements/element_data_store_v3.svelte'; import { events_loc, events_sess, diff --git a/src/routes/events/[event_id]/(pres_mgmt)/event_page_menu.svelte b/src/routes/events/[event_id]/(pres_mgmt)/event_page_menu.svelte index 0af0389a..f097ccfd 100644 --- a/src/routes/events/[event_id]/(pres_mgmt)/event_page_menu.svelte +++ b/src/routes/events/[event_id]/(pres_mgmt)/event_page_menu.svelte @@ -20,7 +20,7 @@ import { events_func } from '$lib/ae_events_functions'; import { api } from '$lib/api/api'; - import Element_data_store from '$lib/elements/element_data_store.svelte'; + import Element_data_store from '$lib/elements/element_data_store_v3.svelte'; import Comp__events_menu_nav from '../../ae_comp__events_menu_nav.svelte'; import Comp__pres_mgmt_menu_opts from '../../ae_comp__events_menu_opts.svelte'; import AE_Record_Controls from '$lib/ae_elements/AE_Record_Controls.svelte'; diff --git a/src/routes/events/[event_id]/(pres_mgmt)/location/[event_location_id]/location_page_menu.svelte b/src/routes/events/[event_id]/(pres_mgmt)/location/[event_location_id]/location_page_menu.svelte index d50090a0..2de81fcd 100644 --- a/src/routes/events/[event_id]/(pres_mgmt)/location/[event_location_id]/location_page_menu.svelte +++ b/src/routes/events/[event_id]/(pres_mgmt)/location/[event_location_id]/location_page_menu.svelte @@ -25,7 +25,7 @@ import { events_func } from '$lib/ae_events_functions'; import { api } from '$lib/api/api'; - import Element_data_store from '$lib/elements/element_data_store.svelte'; + import Element_data_store from '$lib/elements/element_data_store_v3.svelte'; import Comp__events_menu_nav from '../../../../ae_comp__events_menu_nav.svelte'; import AE_Record_Controls from '$lib/ae_elements/AE_Record_Controls.svelte'; diff --git a/src/routes/events/[event_id]/(pres_mgmt)/location/[event_location_id]/location_view.svelte b/src/routes/events/[event_id]/(pres_mgmt)/location/[event_location_id]/location_view.svelte index bf9a0a25..2b0125b5 100644 --- a/src/routes/events/[event_id]/(pres_mgmt)/location/[event_location_id]/location_view.svelte +++ b/src/routes/events/[event_id]/(pres_mgmt)/location/[event_location_id]/location_view.svelte @@ -22,7 +22,7 @@ import type { key_val } from '$lib/stores/ae_stores'; // import { ae_util } from '$lib/ae_utils/ae_utils'; import Element_ae_obj_field_editor_v3 from '$lib/elements/element_ae_obj_field_editor_v3.svelte'; - import Element_data_store from '$lib/elements/element_data_store.svelte'; + import Element_data_store from '$lib/elements/element_data_store_v3.svelte'; let ae_promises: key_val = $state({}); // let ae_tmp: key_val = {}; diff --git a/src/routes/events/[event_id]/(pres_mgmt)/locations/+page.svelte b/src/routes/events/[event_id]/(pres_mgmt)/locations/+page.svelte index 1c78f321..72786c5d 100644 --- a/src/routes/events/[event_id]/(pres_mgmt)/locations/+page.svelte +++ b/src/routes/events/[event_id]/(pres_mgmt)/locations/+page.svelte @@ -14,7 +14,7 @@ import type { key_val } from '$lib/stores/ae_stores'; import { ae_util } from '$lib/ae_utils/ae_utils'; - import Element_data_store from '$lib/elements/element_data_store.svelte'; + import Element_data_store from '$lib/elements/element_data_store_v3.svelte'; let ae_promises: key_val = {}; let ae_tmp: key_val = {}; diff --git a/src/routes/events/[event_id]/(pres_mgmt)/locations/locations_page_menu.svelte b/src/routes/events/[event_id]/(pres_mgmt)/locations/locations_page_menu.svelte index 2f3103ea..850cc7ff 100644 --- a/src/routes/events/[event_id]/(pres_mgmt)/locations/locations_page_menu.svelte +++ b/src/routes/events/[event_id]/(pres_mgmt)/locations/locations_page_menu.svelte @@ -14,7 +14,7 @@ events_slct } from '$lib/stores/ae_events_stores'; - import Element_data_store from '$lib/elements/element_data_store.svelte'; + import Element_data_store from '$lib/elements/element_data_store_v3.svelte'; import Comp__events_menu_nav from '../../../ae_comp__events_menu_nav.svelte'; let show_modal = $state(false); diff --git a/src/routes/events/[event_id]/(pres_mgmt)/presenter/[presenter_id]/+page.svelte b/src/routes/events/[event_id]/(pres_mgmt)/presenter/[presenter_id]/+page.svelte index ef806084..d74569e4 100644 --- a/src/routes/events/[event_id]/(pres_mgmt)/presenter/[presenter_id]/+page.svelte +++ b/src/routes/events/[event_id]/(pres_mgmt)/presenter/[presenter_id]/+page.svelte @@ -11,7 +11,7 @@ // Imports (external and then internal) // import type { key_val } from '$lib/stores/ae_stores'; import { ae_util } from '$lib/ae_utils/ae_utils'; - import Element_data_store from '$lib/elements/element_data_store.svelte'; + import Element_data_store from '$lib/elements/element_data_store_v3.svelte'; import { liveQuery } from 'dexie'; import { Modal } from 'flowbite-svelte'; diff --git a/src/routes/events/[event_id]/(pres_mgmt)/presenter/[presenter_id]/ae_comp__event_presenter_form_agree.svelte b/src/routes/events/[event_id]/(pres_mgmt)/presenter/[presenter_id]/ae_comp__event_presenter_form_agree.svelte index 0c8ed7f8..4ffeeab4 100644 --- a/src/routes/events/[event_id]/(pres_mgmt)/presenter/[presenter_id]/ae_comp__event_presenter_form_agree.svelte +++ b/src/routes/events/[event_id]/(pres_mgmt)/presenter/[presenter_id]/ae_comp__event_presenter_form_agree.svelte @@ -17,7 +17,7 @@ import type { key_val } from '$lib/stores/ae_stores'; import { ae_util } from '$lib/ae_utils/ae_utils'; import { api } from '$lib/api/api'; - import Element_data_store from '$lib/elements/element_data_store.svelte'; + import Element_data_store from '$lib/elements/element_data_store_v3.svelte'; import { ae_loc, diff --git a/src/routes/events/[event_id]/(pres_mgmt)/presenter/[presenter_id]/presenter_page_menu.svelte b/src/routes/events/[event_id]/(pres_mgmt)/presenter/[presenter_id]/presenter_page_menu.svelte index e2f7ecde..987d59ce 100644 --- a/src/routes/events/[event_id]/(pres_mgmt)/presenter/[presenter_id]/presenter_page_menu.svelte +++ b/src/routes/events/[event_id]/(pres_mgmt)/presenter/[presenter_id]/presenter_page_menu.svelte @@ -25,7 +25,7 @@ import { events_func } from '$lib/ae_events_functions'; import { api } from '$lib/api/api'; - import Element_data_store from '$lib/elements/element_data_store.svelte'; + import Element_data_store from '$lib/elements/element_data_store_v3.svelte'; import Comp__events_menu_nav from '../../../../ae_comp__events_menu_nav.svelte'; import AE_Record_Controls from '$lib/ae_elements/AE_Record_Controls.svelte'; diff --git a/src/routes/events/[event_id]/(pres_mgmt)/reports/event_reports_page_menu.svelte b/src/routes/events/[event_id]/(pres_mgmt)/reports/event_reports_page_menu.svelte index b331484a..03015d75 100644 --- a/src/routes/events/[event_id]/(pres_mgmt)/reports/event_reports_page_menu.svelte +++ b/src/routes/events/[event_id]/(pres_mgmt)/reports/event_reports_page_menu.svelte @@ -14,7 +14,7 @@ events_slct } from '$lib/stores/ae_events_stores'; - import Element_data_store from '$lib/elements/element_data_store.svelte'; + import Element_data_store from '$lib/elements/element_data_store_v3.svelte'; import Comp__events_menu_nav from '../../../ae_comp__events_menu_nav.svelte'; let show_modal = $state(false); diff --git a/src/routes/events/[event_id]/(pres_mgmt)/session/[session_id]/ae_comp__event_session_poc_form_agree.svelte b/src/routes/events/[event_id]/(pres_mgmt)/session/[session_id]/ae_comp__event_session_poc_form_agree.svelte index 506d69cf..d26ce21e 100644 --- a/src/routes/events/[event_id]/(pres_mgmt)/session/[session_id]/ae_comp__event_session_poc_form_agree.svelte +++ b/src/routes/events/[event_id]/(pres_mgmt)/session/[session_id]/ae_comp__event_session_poc_form_agree.svelte @@ -29,7 +29,7 @@ import { events_func } from '$lib/ae_events_functions'; // Import components and elements - import Element_data_store from '$lib/elements/element_data_store.svelte'; + import Element_data_store from '$lib/elements/element_data_store_v3.svelte'; import { Check, CheckCircle, LoaderCircle, TriangleAlert, X } from '@lucide/svelte'; // Local Variables let ae_promises: key_val = $state({}); diff --git a/src/routes/events/[event_id]/(pres_mgmt)/session/[session_id]/session_page_menu.svelte b/src/routes/events/[event_id]/(pres_mgmt)/session/[session_id]/session_page_menu.svelte index 628d263f..484165dc 100644 --- a/src/routes/events/[event_id]/(pres_mgmt)/session/[session_id]/session_page_menu.svelte +++ b/src/routes/events/[event_id]/(pres_mgmt)/session/[session_id]/session_page_menu.svelte @@ -27,7 +27,7 @@ import { events_func } from '$lib/ae_events_functions'; import { api } from '$lib/api/api'; - import Element_data_store from '$lib/elements/element_data_store.svelte'; + import Element_data_store from '$lib/elements/element_data_store_v3.svelte'; import Sign_in_out from '../../../sign_in_out.svelte'; import Comp__events_menu_nav from '../../../../ae_comp__events_menu_nav.svelte'; import AE_Record_Controls from '$lib/ae_elements/AE_Record_Controls.svelte'; diff --git a/src/routes/idaa/(idaa)/recovery_meetings/+page.svelte b/src/routes/idaa/(idaa)/recovery_meetings/+page.svelte index fc387924..8b9e0f2b 100644 --- a/src/routes/idaa/(idaa)/recovery_meetings/+page.svelte +++ b/src/routes/idaa/(idaa)/recovery_meetings/+page.svelte @@ -23,7 +23,7 @@ import { ae_loc, ae_api } from '$lib/stores/ae_stores'; import { events_func } from '$lib/ae_events_functions'; - import Element_data_store from '$lib/elements/element_data_store.svelte'; + import Element_data_store from '$lib/elements/element_data_store_v3.svelte'; import Comp__event_obj_qry from './ae_idaa_comp__event_obj_qry.svelte'; import Comp__event_obj_li_wrapper from './ae_idaa_comp__event_obj_li_wrapper.svelte'; diff --git a/src/routes/idaa/(idaa)/video_conferences/+page.svelte b/src/routes/idaa/(idaa)/video_conferences/+page.svelte index da7765c5..3e540dbb 100644 --- a/src/routes/idaa/(idaa)/video_conferences/+page.svelte +++ b/src/routes/idaa/(idaa)/video_conferences/+page.svelte @@ -160,7 +160,9 @@ meta_json: { duration: meeting_duration, participants: participants_array, - participant_count: participants_array.length + participant_count: participants_array.length, + // Verified Novi UUID of the moderator who started this log + moderator_novi_uuid: $idaa_loc.novi_uuid ?? null } }; try { @@ -194,13 +196,15 @@ api.on('participantLeft', (participant: { id: string }) => { console.log('Jitsi Event: participantLeft', participant); - if (meeting_participants.has(participant.id)) { + // Capture name before removing from map — it won't be available after delete + const p_info = meeting_participants.get(participant.id); + if (p_info) { meeting_participants.delete(participant.id); update_primary_activity_log(); - // NOTE: We also want to log this as a discrete event create_discrete_activity_log('jitsi_meeting_participant_left', 'participantLeft', { attendee_id: participant.id, + full_name: p_info.displayName, }); } }); @@ -232,7 +236,16 @@ api.on('videoConferenceLeft', () => { console.log('Jitsi Event: videoConferenceLeft'); if (duration_timer_id) clearInterval(duration_timer_id); - // meeting_duration = '00:00:00'; + + // Do a final update to the primary log so it captures the true end state, + // then log the meeting end as a discrete event for the timeline. + if (is_moderator && primary_activity_log_id) { + update_primary_activity_log(); + create_discrete_activity_log('jitsi_meeting_end', 'videoConferenceLeft', { + final_duration: meeting_duration, + final_participant_count: meeting_participants.size, + }); + } }); api.on('readyToClose', () => { diff --git a/src/routes/idaa/+layout.svelte b/src/routes/idaa/+layout.svelte index 2c443b13..4c2aa91d 100644 --- a/src/routes/idaa/+layout.svelte +++ b/src/routes/idaa/+layout.svelte @@ -21,7 +21,7 @@ } from '$lib/stores/ae_stores'; import { core_func } from '$lib/ae_core/ae_core_functions'; import { idaa_loc, idaa_sess, idaa_slct } from '$lib/stores/ae_idaa_stores'; - import Element_data_store from '$lib/elements/element_data_store.svelte'; + import Element_data_store from '$lib/elements/element_data_store_v3.svelte'; interface Props { /** @type {import('./$types').LayoutData} */ diff --git a/src/routes/idaa/jitsi_reports/+page.svelte b/src/routes/idaa/jitsi_reports/+page.svelte index ef732ecb..fa871b58 100644 --- a/src/routes/idaa/jitsi_reports/+page.svelte +++ b/src/routes/idaa/jitsi_reports/+page.svelte @@ -1,120 +1,428 @@ Æ: Jitsi Meeting Reports -
-

Jitsi Meeting Reports

+
- {#await data.streamed.meetings} -
-
-
-
-
+ +
+

Jitsi Meeting Reports

+
+ +
- {:then meetings} - {#if meetings && meetings.length > 0} +
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ {#if filters_are_modified} + + {/if} +
+ + {#if meetings_loading} + +
+ {#each [1, 2, 3, 4] as _, i (i)} +
+ {/each} +
+ + {:else if meetings_error} + +
+
Error Loading Reports
+

An error occurred while fetching the meeting reports:

+
{meetings_error}
+
+ + {:else} + + {#if meetings_all.length > 0} +
+
+
{summary.count}
+
Meetings Shown
+
+
+
{summary.total_participants}
+
Total Participants
+
+
+
{summary.avg_duration}
+
Avg Duration
+
+
+
{summary.total_duration}
+
Total Duration
+
+
+ {/if} + + + {#if meetings_filtered.length > 0}
- {#each meetings as meeting (meeting.meeting_id)} -
+ {#each meetings_filtered as meeting (meeting.meeting_id)} +
+ + -
toggle_accordion(meeting.meeting_id)}> -
-
- -

{meeting.room_name}

-

{new Date(meeting.start_time).toLocaleString()}

+
toggle_accordion(meeting.meeting_id)} + > +
+
+
{meeting.room_name}
+
{new Date(meeting.start_time).toLocaleString()}
-
- Duration: {meeting.final_duration} - Participants: {meeting.final_participant_count} -
-
- - + +
+ +
-
+ +
+ {meeting.final_duration} + + + {meeting.final_participant_count} + {meeting.final_participant_count === 1 ? 'participant' : 'participants'} + +
+
+ + {#if open_accordions[meeting.meeting_id]} -
+
+ +
- -

Event Timeline

+
Event Timeline
{#if meeting.events && meeting.events.length > 0} -
    +
      {#each meeting.events as event, i (i)} -
    • - [{new Date(event.timestamp).toLocaleTimeString()}] - {ae_util.to_title_case(event.action.replace('jitsi_meeting_', ''))} - {#if event.details.full_name} - - by {event.details.full_name} - {/if} +
    • + + [{new Date(event.timestamp).toLocaleTimeString()}] + + + + {ae_util.to_title_case(event.action.replace('jitsi_meeting_', ''))} + + {#if event.details?.full_name} + — {event.details.full_name} + {/if} +
    • {/each}
    {:else} -

    No discrete events recorded.

    +

    No discrete events recorded.

    {/if}
+ +
- -

Final Participants

+
+ Final Participants ({meeting.final_participant_count}) +
{#if meeting.final_participants && meeting.final_participants.length > 0} -
- - - - - +
NameRole
+ + + + + + + + {#each meeting.final_participants as participant (participant.displayName)} + + + - - - {#each meeting.final_participants as participant (participant.displayName)} - - - - - {/each} - -
NameRole
{participant.displayName}{ae_util.to_title_case(participant.role)}
{participant.displayName}{ae_util.to_title_case(participant.role)}
-
+ {/each} + + {:else} -

No participant data available.

+

No participant data available.

{/if}
+
{/if}
{/each}
+ {:else} -
-

No Meeting Reports Found

-

There are no Jitsi activity logs to display.

+ +
+ {#if meetings_all.length > 0} +
No meetings match the current filters
+

Try lowering the minimum participants or clearing the date range.

+ + {:else} +
No Meeting Reports Found
+

There are no Jitsi activity logs to display.

+ {/if}
{/if} - {:catch error} -
-

Error Loading Reports

-

An error occurred while fetching the meeting reports:

-
{error.message}
-
- {/await} + + {/if} +
diff --git a/src/routes/journals/+layout.svelte b/src/routes/journals/+layout.svelte index ac919490..c8f7e29c 100644 --- a/src/routes/journals/+layout.svelte +++ b/src/routes/journals/+layout.svelte @@ -17,7 +17,7 @@ journals_slct, journals_trig } from '$lib/ae_journals/ae_journals_stores'; - import Element_data_store from '$lib/elements/element_data_store.svelte'; + import Element_data_store from '$lib/elements/element_data_store_v3.svelte'; import Help_tech from '$lib/app_components/e_app_help_tech.svelte'; // *** Setup Svelte properties diff --git a/src/routes/testing/data_store_v3/+page.svelte b/src/routes/testing/data_store_v3/+page.svelte index 3b8942b8..9ba1e904 100644 --- a/src/routes/testing/data_store_v3/+page.svelte +++ b/src/routes/testing/data_store_v3/+page.svelte @@ -1,5 +1,5 @@