Files
OSIT-AE-App-Svelte/src/routes/events/ae_comp__event_session_obj_li.svelte
Scott Idem d21e2f8e6f refactor: standardize event file actions and apply batch formatting
- Updated 'create_event_file_obj_from_hosted_file_async' to use the modern V3 action endpoint.
- Standardized 'prevent_default' helper names in root Event and Archive components.
- Applied batch formatting (printWidth: 80) across the settings and events modules.
2026-02-06 16:17:31 -05:00

387 lines
18 KiB
Svelte
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script lang="ts">
interface Props {
log_lvl?: number;
container_class_li?: string | Array<string>;
lq__event_session_obj_li: any;
hide__session_location?: boolean;
hide__session_poc?: boolean;
hide__admin?: boolean;
hide__launcher_link_legacy?: boolean;
hide__launcher_link?: boolean;
hide__location_link?: boolean;
show__session_files?: boolean;
show__session_presentations?: boolean;
}
let {
log_lvl = 0,
container_class_li = [],
lq__event_session_obj_li,
hide__session_location = $bindable(false),
hide__session_poc = $bindable(false),
hide__admin = $bindable(false),
hide__launcher_link_legacy = $bindable(false),
hide__launcher_link = $bindable(false),
hide__location_link = $bindable(false),
show__session_files = $bindable(false),
show__session_presentations = $bindable(false)
}: Props = $props();
import { ae_util } from '$lib/ae_utils/ae_utils';
import {
LoaderCircle,
Presentation,
Check,
Eye,
EyeOff,
Mail,
MapPin,
User,
ChevronDown,
ChevronUp,
SendHorizontal,
Rocket,
Bell,
BellOff,
Edit,
FileSearch,
Search,
CalendarDays,
Clock
} from 'lucide-svelte';
import Element_ae_crud_v2 from '$lib/elements/element_ae_crud_v2.svelte';
import Comp_event_presenter_obj_li from './[event_id]/(pres_mgmt)/presenter/ae_comp__event_presenter_obj_li_wrapper.svelte';
import Element_manage_event_file_li from '$lib/elements/element_manage_event_file_li_direct.svelte';
import Comp_event_session_alert from './[event_id]/(pres_mgmt)/session/ae_comp__event_session_alert.svelte';
import { core_func } from '$lib/ae_core/ae_core_functions';
import { ae_loc, ae_api, ae_snip } from '$lib/stores/ae_stores';
import {
events_loc,
events_sess,
events_slct
} from '$lib/stores/ae_events_stores';
let show_details_kv: Record<string, boolean> = $state({});
// Derived list of visible items (Standardized Pattern 2026-01-27)
let visible_session_obj_li = $derived(
(() => {
const list = $lq__event_session_obj_li;
if (list === undefined || list === null) return null;
if (!Array.isArray(list)) return [];
const filtered = list.filter((item: any) => {
if (!item) return false;
if ($ae_loc.trusted_access) return true;
return !item.hide;
});
if (log_lvl)
console.log(
`visible_session_obj_li: Input=${list.length}, Output=${filtered.length}`
);
return filtered;
})()
);
function toggle_details(id: string) {
show_details_kv[id] = !show_details_kv[id];
}
</script>
<section
class="ae_comp event_session_obj_li px-0.5 py-2 space-y-2 min-w-full w-full container overflow-x-auto {container_class_li}"
>
{#if visible_session_obj_li === null}
<div class="flex flex-col items-center justify-center p-10 opacity-50">
<LoaderCircle size="3em" class="animate-spin mb-2" />
<p>Loading sessions...</p>
</div>
{:else if visible_session_obj_li.length > 0}
<header
class="w-full flex flex-row gap-2 items-center justify-start mb-2 px-2"
>
<h2 class="text-sm text-gray-500 font-normal">Sessions:</h2>
<span
class="badge preset-tonal-success font-bold text-lg px-3 py-1"
>
{visible_session_obj_li.length}<span
class="text-gray-400 dark:text-gray-600">&times;</span
>
</span>
</header>
<table class="table table-auto table-striped w-full">
<thead>
<tr class="bg-surface-100-900">
<th>Session</th>
<th class="hidden md:table-cell">Schedule</th>
<th class:hidden={hide__session_location}>Location</th>
<th class:hidden={hide__session_poc}>POC</th>
<th
class:hidden={!$ae_loc.edit_mode ||
!$ae_loc.adv_mode ||
hide__admin}>Admin</th
>
</tr>
</thead>
<tbody>
{#each visible_session_obj_li as session_obj, index (session_obj.id || session_obj.event_session_id || session_obj.event_session_id_random || index)}
<tr
class="relative"
class:opacity-50={session_obj?.hide}
class:variant-soft-warning={!session_obj?.enable}
>
<td>
{#if session_obj?.alert && $ae_loc.trusted_access}
<Comp_event_session_alert
event_session_obj={session_obj}
{log_lvl}
/>
{/if}
<div class="flex flex-col gap-1">
<div class="flex items-center gap-2">
<a
href="/events/{session_obj?.event_id}/session/{session_obj?.event_session_id}"
class="flex flex-row gap-2 items-center font-bold text-lg hover:text-primary-500 text-left"
>
{#if session_obj?.hide}
<EyeOff
size="1em"
class="text-gray-400 flex-none"
/>
{:else}
<Presentation
size="1em"
class="text-primary-500 flex-none"
/>
{/if}
<span>{session_obj?.name}</span>
{#if session_obj?.file_count_all}
<span
class="badge preset-tonal-success flex items-center gap-1 text-xs py-0 px-1"
>
<Check size="1em" />
{session_obj.file_count_all}
</span>
{/if}
</a>
{#if (show__session_presentations || show__session_files) && $ae_loc.manager_access}
<button
type="button"
class="btn btn-icon btn-sm variant-soft-surface"
onclick={() =>
toggle_details(
session_obj.event_session_id
)}
>
{#if show_details_kv[session_obj.event_session_id]}
<ChevronUp size="1.2em" />
{:else}
<ChevronDown size="1.2em" />
{/if}
</button>
{/if}
</div>
<!-- Mobile Schedule Summary -->
<div
class="md:hidden text-xs text-surface-500 flex flex-wrap gap-x-3 gap-y-1"
>
<span class="flex items-center gap-1"
><CalendarDays size="1em" />
{ae_util.iso_datetime_formatter(
session_obj?.start_datetime,
'date_short_month_day'
)}</span
>
<span class="flex items-center gap-1"
><Clock size="1em" />
{ae_util.iso_datetime_formatter(
session_obj?.start_datetime,
'time_12_short'
)}</span
>
</div>
{#if show_details_kv[session_obj.event_session_id]}
<div
class="p-2 bg-surface-500/5 rounded-lg border border-surface-500/10 mt-1"
>
{#if show__session_presentations && $ae_loc.manager_access}
<Comp_event_presenter_obj_li
link_to_type={'event_session'}
link_to_id={session_obj?.event_session_id}
display_mode={'minimal'}
{log_lvl}
/>
{/if}
{#if show__session_files && $ae_loc.manager_access}
<Element_manage_event_file_li
link_to_type={'event_session'}
link_to_id={session_obj?.event_session_id}
allow_basic={true}
allow_moderator={true}
display_mode={'minimal'}
/>
{/if}
</div>
{/if}
</div>
</td>
<td class="hidden md:table-cell">
<div class="flex flex-col text-xs font-medium">
<span class="text-surface-900-100"
>{ae_util.iso_datetime_formatter(
session_obj?.start_datetime,
'dddd, MMM D'
)}</span
>
<span class="text-surface-500 whitespace-nowrap"
>{ae_util.iso_datetime_formatter(
session_obj?.start_datetime,
'time_12_short'
)} {ae_util.iso_datetime_formatter(
session_obj?.end_datetime,
'time_12_short'
)}</span
>
</div>
</td>
<td class:hidden={hide__session_location}>
<div class="flex flex-col gap-1 min-w-32">
<span class="text-xs font-semibold"
>{session_obj?.event_location_name ??
'--'}</span
>
<div class="flex gap-1">
{#if !hide__launcher_link}
<a
href="/events/{session_obj?.event_id}/launcher/{session_obj?.event_location_id}?session_id={session_obj?.event_session_id}"
class="btn btn-icon btn-xs preset-tonal-tertiary"
title="Svelte Launcher"
><Rocket size="1em" /></a
>
{/if}
{#if !hide__location_link}
<a
href="/events/{session_obj?.event_id}/location/{session_obj?.event_location_id}"
class="btn btn-icon btn-xs preset-tonal-surface"
title="Location Details"
><MapPin size="1em" /></a
>
{/if}
</div>
</div>
</td>
<td class:hidden={hide__session_poc}>
<div class="flex flex-col text-xs min-w-32">
{#if session_obj?.poc_person_full_name}
<span
class="font-bold flex items-center gap-1"
><User size="1em" />
{session_obj.poc_person_full_name}</span
>
{#if $ae_loc.trusted_access && session_obj?.poc_person_primary_email}
<a
href="mailto:{session_obj.poc_person_primary_email}"
class="text-primary-500 hover:underline flex items-center gap-1"
><Mail size="1em" /> Email</a
>
{/if}
{:else}
<span class="opacity-30">--</span>
{/if}
</div>
</td>
<td
class:hidden={!$ae_loc.edit_mode ||
!$ae_loc.adv_mode ||
hide__admin}
>
<div class="flex gap-1">
<button
type="button"
class="btn btn-icon btn-xs {session_obj?.hide
? 'preset-tonal-error'
: 'preset-tonal-secondary'}"
onclick={() =>
core_func.update_ae_obj_id_crud_v2({
api_cfg: $ae_api,
object_type: 'event_session',
object_id:
session_obj.event_session_id,
field_name: 'hide',
new_field_value: !session_obj.hide,
log_lvl: 1
})}
>
{#if session_obj?.hide}<EyeOff
size="1.2em"
/>{:else}<Eye size="1.2em" />{/if}
</button>
<button
type="button"
class="btn btn-icon btn-xs {session_obj?.alert
? 'preset-tonal-warning'
: 'preset-tonal-surface'}"
onclick={() =>
core_func.update_ae_obj_id_crud_v2({
api_cfg: $ae_api,
object_type: 'event_session',
object_id:
session_obj.event_session_id,
field_name: 'alert',
new_field_value: !session_obj.alert,
log_lvl: 1
})}
>
{#if session_obj?.alert}<Bell
size="1.2em"
/>{:else}<BellOff size="1.2em" />{/if}
</button>
</div>
</td>
</tr>
{/each}
</tbody>
</table>
{:else}
<div
class="flex flex-col items-center justify-center p-20 opacity-50 text-center bg-surface-50 dark:bg-surface-900/50 rounded-lg border border-dashed border-surface-300"
>
<FileSearch size="3em" class="mb-2 opacity-20 mx-auto" />
<p class="text-xl">No sessions found matching your criteria.</p>
<p class="text-sm">Try adjusting your filters or search terms.</p>
</div>
{/if}
</section>