Prettier for Events as a whole. Everything else under that primary directory.
This commit is contained in:
@@ -1,73 +1,73 @@
|
||||
<script lang="ts">
|
||||
// console.log(`ae_events_pres_mgmt +page data:`, data);
|
||||
// console.log(`ae_events_pres_mgmt Data Params:`, data.url.searchParams.get('event_id'));
|
||||
// console.log(`ae_events_pres_mgmt +page data:`, data);
|
||||
// console.log(`ae_events_pres_mgmt Data Params:`, data.url.searchParams.get('event_id'));
|
||||
|
||||
import { onMount } from 'svelte';
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
import { liveQuery } from 'dexie';
|
||||
import { db_events } from '$lib/ae_events/db_events';
|
||||
import {
|
||||
ae_loc,
|
||||
ae_sess,
|
||||
ae_api,
|
||||
slct,
|
||||
slct_trigger
|
||||
} from '$lib/stores/ae_stores';
|
||||
// import {
|
||||
// events_loc,
|
||||
// events_slct,
|
||||
// events_trigger
|
||||
// } from '$lib/stores/ae_events_stores';
|
||||
import { ae_util } from '$lib/ae_utils/ae_utils';
|
||||
import { CalendarDays, LoaderCircle, TriangleAlert } from '@lucide/svelte';
|
||||
import { page } from '$app/stores';
|
||||
import { liveQuery } from 'dexie';
|
||||
import { db_events } from '$lib/ae_events/db_events';
|
||||
import {
|
||||
ae_loc,
|
||||
ae_sess,
|
||||
ae_api,
|
||||
slct,
|
||||
slct_trigger
|
||||
} from '$lib/stores/ae_stores';
|
||||
// import {
|
||||
// events_loc,
|
||||
// events_slct,
|
||||
// events_trigger
|
||||
// } from '$lib/stores/ae_events_stores';
|
||||
import { ae_util } from '$lib/ae_utils/ae_utils';
|
||||
import { CalendarDays, LoaderCircle, TriangleAlert } from '@lucide/svelte';
|
||||
import { page } from '$app/stores';
|
||||
|
||||
interface Props {
|
||||
data: any;
|
||||
interface Props {
|
||||
data: any;
|
||||
}
|
||||
|
||||
let { data }: Props = $props();
|
||||
|
||||
let lq__event_obj_li = $derived(
|
||||
liveQuery(async () => {
|
||||
const account_id = $page.data.account_id;
|
||||
if (!account_id) return [];
|
||||
let results = await db_events.event
|
||||
.where('account_id')
|
||||
.equals(account_id)
|
||||
.reverse()
|
||||
.sortBy('start_datetime');
|
||||
return results;
|
||||
})
|
||||
);
|
||||
|
||||
let items_per_page = 10;
|
||||
let current_page = $state(1);
|
||||
|
||||
let paginated_events = $derived(() => {
|
||||
const start = (current_page - 1) * items_per_page;
|
||||
const end = start + items_per_page;
|
||||
return $lq__event_obj_li?.slice(start, end) ?? [];
|
||||
});
|
||||
|
||||
let total_events = $derived($lq__event_obj_li?.length ?? 0);
|
||||
let total_pages = $derived(Math.ceil(total_events / items_per_page));
|
||||
|
||||
function next_page() {
|
||||
if (current_page < total_pages) {
|
||||
current_page++;
|
||||
}
|
||||
}
|
||||
|
||||
let { data }: Props = $props();
|
||||
|
||||
let lq__event_obj_li = $derived(
|
||||
liveQuery(async () => {
|
||||
const account_id = $page.data.account_id;
|
||||
if (!account_id) return [];
|
||||
let results = await db_events.event
|
||||
.where('account_id')
|
||||
.equals(account_id)
|
||||
.reverse()
|
||||
.sortBy('start_datetime');
|
||||
return results;
|
||||
})
|
||||
);
|
||||
|
||||
let items_per_page = 10;
|
||||
let current_page = $state(1);
|
||||
|
||||
let paginated_events = $derived(() => {
|
||||
const start = (current_page - 1) * items_per_page;
|
||||
const end = start + items_per_page;
|
||||
return $lq__event_obj_li?.slice(start, end) ?? [];
|
||||
});
|
||||
|
||||
let total_events = $derived($lq__event_obj_li?.length ?? 0);
|
||||
let total_pages = $derived(Math.ceil(total_events / items_per_page));
|
||||
|
||||
function next_page() {
|
||||
if (current_page < total_pages) {
|
||||
current_page++;
|
||||
}
|
||||
function prev_page() {
|
||||
if (current_page > 1) {
|
||||
current_page--;
|
||||
}
|
||||
}
|
||||
|
||||
function prev_page() {
|
||||
if (current_page > 1) {
|
||||
current_page--;
|
||||
}
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
// console.log('Events - Presentation Management: +page.svelte');
|
||||
});
|
||||
onMount(() => {
|
||||
// console.log('Events - Presentation Management: +page.svelte');
|
||||
});
|
||||
</script>
|
||||
|
||||
<h2 class="h3">
|
||||
@@ -119,12 +119,11 @@
|
||||
{#each $lq__event_obj_li as event_obj (event_obj.event_id)}
|
||||
<li class:dim={event_obj?.hide}>
|
||||
<span
|
||||
class="w-full flex flex-row gap-1 items-center justify-between"
|
||||
>
|
||||
class="flex w-full flex-row items-center justify-between gap-1">
|
||||
<!-- We do not want to show events more than 8 months old. -->
|
||||
{#if new Date(event_obj.start_datetime ?? '').getTime() > new Date().getTime() - 1000 * 60 * 60 * 24 * 30 * 8 || $ae_loc.trusted_access}
|
||||
<span>
|
||||
<CalendarDays size="1em" class="inline mx-1" />
|
||||
<CalendarDays size="1em" class="mx-1 inline" />
|
||||
{ae_util.iso_datetime_formatter(
|
||||
event_obj.start_datetime,
|
||||
'date_long'
|
||||
@@ -135,7 +134,7 @@
|
||||
</strong>
|
||||
{:else}
|
||||
<span>
|
||||
<CalendarDays size="1em" class="inline mx-1" />
|
||||
<CalendarDays size="1em" class="mx-1 inline" />
|
||||
{ae_util.iso_datetime_formatter(
|
||||
event_obj.start_datetime,
|
||||
'date_long'
|
||||
@@ -148,36 +147,31 @@
|
||||
</span>
|
||||
|
||||
<span
|
||||
class="w-full flex flex-row gap-1 items-center justify-evenly"
|
||||
>
|
||||
class="flex w-full flex-row items-center justify-evenly gap-1">
|
||||
{#if $ae_loc.authenticated_access}
|
||||
<a
|
||||
data-sveltekit-reload
|
||||
href="/events/{event_obj.event_id}"
|
||||
class="btn btn-sm preset-tonal-secondary border border-secondary-500 hover:preset-filled-secondary-500"
|
||||
title="Presentation Management for {event_obj.name}"
|
||||
>
|
||||
class="btn btn-sm preset-tonal-secondary border-secondary-500 hover:preset-filled-secondary-500 border"
|
||||
title="Presentation Management for {event_obj.name}">
|
||||
Pres Mgmt
|
||||
</a>
|
||||
<a
|
||||
href="/events/{event_obj.event_id}/badges"
|
||||
class="btn btn-sm preset-tonal-secondary border border-secondary-500 hover:preset-filled-secondary-500"
|
||||
title="Badge Management for {event_obj.name}"
|
||||
>
|
||||
class="btn btn-sm preset-tonal-secondary border-secondary-500 hover:preset-filled-secondary-500 border"
|
||||
title="Badge Management for {event_obj.name}">
|
||||
Badges
|
||||
</a>
|
||||
<a
|
||||
href="/events/{event_obj.event_id}/leads"
|
||||
class="btn btn-sm preset-tonal-secondary border border-secondary-500 hover:preset-filled-secondary-500"
|
||||
title="Exhibitor Leads for {event_obj.name}"
|
||||
>
|
||||
class="btn btn-sm preset-tonal-secondary border-secondary-500 hover:preset-filled-secondary-500 border"
|
||||
title="Exhibitor Leads for {event_obj.name}">
|
||||
Leads
|
||||
</a>
|
||||
<a
|
||||
href="/events/{event_obj.event_id}/launcher"
|
||||
class="btn btn-sm preset-tonal-secondary border border-secondary-500 hover:preset-filled-secondary-500"
|
||||
title="Event Launcher for {event_obj.name}"
|
||||
>
|
||||
class="btn btn-sm preset-tonal-secondary border-secondary-500 hover:preset-filled-secondary-500 border"
|
||||
title="Event Launcher for {event_obj.name}">
|
||||
Launcher
|
||||
</a>
|
||||
{/if}
|
||||
@@ -185,9 +179,8 @@
|
||||
<a
|
||||
data-sveltekit-reload
|
||||
href="/event/{event_obj.event_id}"
|
||||
class="btn btn-sm preset-tonal-warning border border-warning-500 hover:preset-filled-warning-500"
|
||||
title="Legacy Presentation Management System (Flask/Svelte) for {event_obj.name}"
|
||||
>
|
||||
class="btn btn-sm preset-tonal-warning border-warning-500 hover:preset-filled-warning-500 border"
|
||||
title="Legacy Presentation Management System (Flask/Svelte) for {event_obj.name}">
|
||||
Legacy Pres Mgmt
|
||||
</a>
|
||||
{/if}
|
||||
@@ -195,31 +188,29 @@
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
<div class="flex justify-center items-center space-x-4 mt-4">
|
||||
<div class="mt-4 flex items-center justify-center space-x-4">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-sm"
|
||||
onclick={prev_page}
|
||||
disabled={current_page === 1}>Previous</button
|
||||
>
|
||||
disabled={current_page === 1}>Previous</button>
|
||||
<span>Page {current_page} of {total_pages}</span>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-sm"
|
||||
onclick={next_page}
|
||||
disabled={current_page === total_pages}>Next</button
|
||||
>
|
||||
disabled={current_page === total_pages}>Next</button>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="flex flex-row items-center justify-center">
|
||||
<TriangleAlert size="1em" class="inline text-error-500 mx-1" />
|
||||
<TriangleAlert size="1em" class="text-error-500 mx-1 inline" />
|
||||
<span>No events available to display.</span>
|
||||
<TriangleAlert size="1em" class="inline text-error-500 mx-1" />
|
||||
<TriangleAlert size="1em" class="text-error-500 mx-1 inline" />
|
||||
</div>
|
||||
{/if}
|
||||
{:else}
|
||||
<div class="flex flex-row items-center justify-center">
|
||||
<LoaderCircle size="1em" class="inline animate-spin mx-1" />
|
||||
<LoaderCircle size="1em" class="mx-1 inline animate-spin" />
|
||||
<span>Loading...</span>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@@ -1,314 +1,328 @@
|
||||
<script lang="ts">
|
||||
interface Props {
|
||||
// Exports
|
||||
container_class_li?: string | Array<string>;
|
||||
event_file_id_random_li?: Array<string>;
|
||||
lq__event_file_obj_li: any;
|
||||
allow_basic?: boolean;
|
||||
allow_moderator?: boolean;
|
||||
// export let max_records: number = 100;
|
||||
show_direct_download?: boolean;
|
||||
show_location_fields?: boolean;
|
||||
show_presentation_fields?: boolean;
|
||||
// export let show_presenter_fields: boolean = false;
|
||||
show_session_fields?: boolean;
|
||||
hide_session_code?: boolean;
|
||||
log_lvl?: number;
|
||||
}
|
||||
interface Props {
|
||||
// Exports
|
||||
container_class_li?: string | Array<string>;
|
||||
event_file_id_random_li?: Array<string>;
|
||||
lq__event_file_obj_li: any;
|
||||
allow_basic?: boolean;
|
||||
allow_moderator?: boolean;
|
||||
// export let max_records: number = 100;
|
||||
show_direct_download?: boolean;
|
||||
show_location_fields?: boolean;
|
||||
show_presentation_fields?: boolean;
|
||||
// export let show_presenter_fields: boolean = false;
|
||||
show_session_fields?: boolean;
|
||||
hide_session_code?: boolean;
|
||||
log_lvl?: number;
|
||||
}
|
||||
|
||||
let {
|
||||
container_class_li = [],
|
||||
event_file_id_random_li = [],
|
||||
lq__event_file_obj_li,
|
||||
allow_basic = false,
|
||||
allow_moderator = false,
|
||||
show_direct_download = $bindable(false),
|
||||
show_location_fields = false,
|
||||
show_presentation_fields = false,
|
||||
show_session_fields = false,
|
||||
hide_session_code = false,
|
||||
log_lvl = $bindable(0)
|
||||
}: Props = $props();
|
||||
let {
|
||||
container_class_li = [],
|
||||
event_file_id_random_li = [],
|
||||
lq__event_file_obj_li,
|
||||
allow_basic = false,
|
||||
allow_moderator = false,
|
||||
show_direct_download = $bindable(false),
|
||||
show_location_fields = false,
|
||||
show_presentation_fields = false,
|
||||
show_session_fields = false,
|
||||
hide_session_code = false,
|
||||
log_lvl = $bindable(0)
|
||||
}: Props = $props();
|
||||
|
||||
// Imports
|
||||
// import { liveQuery } from 'dexie';
|
||||
// Imports
|
||||
// import { liveQuery } from 'dexie';
|
||||
|
||||
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 type { key_val } from '$lib/stores/ae_stores';
|
||||
import { ae_util } from '$lib/ae_utils/ae_utils';
|
||||
// import { api } from '$lib/api/api';
|
||||
|
||||
// import { db_events } from '$lib/ae_events/db_events';
|
||||
import {
|
||||
ae_snip,
|
||||
ae_loc,
|
||||
ae_sess,
|
||||
ae_api,
|
||||
ae_trig,
|
||||
slct,
|
||||
slct_trigger
|
||||
} from '$lib/stores/ae_stores';
|
||||
// import { events_loc, events_sess, events_slct, events_trigger, events_trig_kv } from '$lib/stores/ae_events_stores';
|
||||
// import { events_func } from '$lib/ae_events/ae_events_functions';
|
||||
import MyClipboard from '$lib/app_components/e_app_clipboard.svelte';
|
||||
import AE_Comp_Hosted_Files_Download_Button from '$lib/ae_core/ae_comp__hosted_files_download_button.svelte';
|
||||
import { Check, Download, FileImage, FileSpreadsheet, ListOrdered, LoaderCircle, Presentation, ToggleLeft, ToggleRight, TriangleAlert, User } from '@lucide/svelte';
|
||||
// export let display_mode: string = 'default'; // 'default', 'compact', 'minimal', 'launcher'
|
||||
// import { db_events } from '$lib/ae_events/db_events';
|
||||
import {
|
||||
ae_snip,
|
||||
ae_loc,
|
||||
ae_sess,
|
||||
ae_api,
|
||||
ae_trig,
|
||||
slct,
|
||||
slct_trigger
|
||||
} from '$lib/stores/ae_stores';
|
||||
// import { events_loc, events_sess, events_slct, events_trigger, events_trig_kv } from '$lib/stores/ae_events_stores';
|
||||
// import { events_func } from '$lib/ae_events/ae_events_functions';
|
||||
import MyClipboard from '$lib/app_components/e_app_clipboard.svelte';
|
||||
import AE_Comp_Hosted_Files_Download_Button from '$lib/ae_core/ae_comp__hosted_files_download_button.svelte';
|
||||
import {
|
||||
Check,
|
||||
Download,
|
||||
FileImage,
|
||||
FileSpreadsheet,
|
||||
ListOrdered,
|
||||
LoaderCircle,
|
||||
Presentation,
|
||||
ToggleLeft,
|
||||
ToggleRight,
|
||||
TriangleAlert,
|
||||
User
|
||||
} from '@lucide/svelte';
|
||||
// export let display_mode: string = 'default'; // 'default', 'compact', 'minimal', 'launcher'
|
||||
|
||||
// Variables
|
||||
let ae_promises: key_val = $state({});
|
||||
// Variables
|
||||
let ae_promises: key_val = $state({});
|
||||
|
||||
// *** Functions and Logic
|
||||
// *** Functions and Logic
|
||||
|
||||
// Define the list of unacceptable characters if not using the default.
|
||||
// const unacceptable_chars = /[ <>:"/\\|?*]/g;
|
||||
// Define the list of unacceptable characters if not using the default.
|
||||
// const unacceptable_chars = /[ <>:"/\\|?*]/g;
|
||||
|
||||
let horiz_scroll_warning: boolean = $state(false);
|
||||
let horiz_check_element: HTMLElement | null = $state(null);
|
||||
let horiz_scroll_warning: boolean = $state(false);
|
||||
let horiz_check_element: HTMLElement | null = $state(null);
|
||||
|
||||
// PDF → Image conversion state (keyed by event_file_id)
|
||||
// WHY: Poster sessions display files in the Launcher modal via <img> tag — PDFs can't render there.
|
||||
// Presenters upload PDFs which must be converted server-side to high-res webp images.
|
||||
// Button is only shown in edit_mode for PDF files linked to a poster-type session.
|
||||
// Backend: /v3/action/hosted_file/{id}/convert_file runs pdf2image (3840px wide, first page only)
|
||||
// and saves the result as a new hosted_file record linked to the same parent object.
|
||||
type ConvertStatus = 'idle' | 'converting' | 'done' | 'error';
|
||||
let convert_status_kv: Record<string, ConvertStatus> = $state({});
|
||||
let convert_result_kv: Record<string, any> = $state({});
|
||||
// PDF → Image conversion state (keyed by event_file_id)
|
||||
// WHY: Poster sessions display files in the Launcher modal via <img> tag — PDFs can't render there.
|
||||
// Presenters upload PDFs which must be converted server-side to high-res webp images.
|
||||
// Button is only shown in edit_mode for PDF files linked to a poster-type session.
|
||||
// Backend: /v3/action/hosted_file/{id}/convert_file runs pdf2image (3840px wide, first page only)
|
||||
// and saves the result as a new hosted_file record linked to the same parent object.
|
||||
type ConvertStatus = 'idle' | 'converting' | 'done' | 'error';
|
||||
let convert_status_kv: Record<string, ConvertStatus> = $state({});
|
||||
let convert_result_kv: Record<string, any> = $state({});
|
||||
|
||||
async function handle_convert_pdf_to_image(event_file_obj: any) {
|
||||
const file_id = event_file_obj.event_file_id;
|
||||
convert_status_kv[file_id] = 'converting';
|
||||
try {
|
||||
// Link the new image to the most specific parent available
|
||||
const link_to_type = event_file_obj.event_session_id ? 'event_session'
|
||||
: event_file_obj.event_presentation_id ? 'event_presentation'
|
||||
: 'event';
|
||||
const link_to_id = event_file_obj.event_session_id
|
||||
|| event_file_obj.event_presentation_id
|
||||
|| event_file_obj.event_id;
|
||||
const filename_no_ext = (event_file_obj.filename ?? 'poster_image').replace(/\.pdf$/i, '');
|
||||
const url = `${$ae_api.base_url}/v3/hosted_file/${event_file_obj.hosted_file_id}/convert_file`
|
||||
+ `?link_to_type=${encodeURIComponent(link_to_type)}`
|
||||
+ `&link_to_id=${encodeURIComponent(link_to_id)}`
|
||||
+ `&filename_no_ext=${encodeURIComponent(filename_no_ext)}`
|
||||
+ `&to_type=webp`;
|
||||
const resp = await fetch(url, {
|
||||
headers: {
|
||||
'x-aether-api-key': $ae_api.api_secret_key,
|
||||
'x-account-id': String($ae_api.account_id ?? '')
|
||||
}
|
||||
});
|
||||
const body = await resp.json();
|
||||
if (resp.ok && body?.data) {
|
||||
convert_result_kv[file_id] = body.data;
|
||||
convert_status_kv[file_id] = 'done';
|
||||
} else {
|
||||
console.error('[convert_pdf] API error:', body);
|
||||
convert_status_kv[file_id] = 'error';
|
||||
async function handle_convert_pdf_to_image(event_file_obj: any) {
|
||||
const file_id = event_file_obj.event_file_id;
|
||||
convert_status_kv[file_id] = 'converting';
|
||||
try {
|
||||
// Link the new image to the most specific parent available
|
||||
const link_to_type = event_file_obj.event_session_id
|
||||
? 'event_session'
|
||||
: event_file_obj.event_presentation_id
|
||||
? 'event_presentation'
|
||||
: 'event';
|
||||
const link_to_id =
|
||||
event_file_obj.event_session_id ||
|
||||
event_file_obj.event_presentation_id ||
|
||||
event_file_obj.event_id;
|
||||
const filename_no_ext = (
|
||||
event_file_obj.filename ?? 'poster_image'
|
||||
).replace(/\.pdf$/i, '');
|
||||
const url =
|
||||
`${$ae_api.base_url}/v3/hosted_file/${event_file_obj.hosted_file_id}/convert_file` +
|
||||
`?link_to_type=${encodeURIComponent(link_to_type)}` +
|
||||
`&link_to_id=${encodeURIComponent(link_to_id)}` +
|
||||
`&filename_no_ext=${encodeURIComponent(filename_no_ext)}` +
|
||||
`&to_type=webp`;
|
||||
const resp = await fetch(url, {
|
||||
headers: {
|
||||
'x-aether-api-key': $ae_api.api_secret_key,
|
||||
'x-account-id': String($ae_api.account_id ?? '')
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('[convert_pdf] Fetch failed:', err);
|
||||
});
|
||||
const body = await resp.json();
|
||||
if (resp.ok && body?.data) {
|
||||
convert_result_kv[file_id] = body.data;
|
||||
convert_status_kv[file_id] = 'done';
|
||||
} else {
|
||||
console.error('[convert_pdf] API error:', body);
|
||||
convert_status_kv[file_id] = 'error';
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('[convert_pdf] Fetch failed:', err);
|
||||
convert_status_kv[file_id] = 'error';
|
||||
}
|
||||
}
|
||||
|
||||
// Check if element is scrolling horizontally
|
||||
$effect(() => {
|
||||
if (
|
||||
horiz_check_element &&
|
||||
horiz_check_element.scrollWidth > horiz_check_element.offsetWidth
|
||||
) {
|
||||
horiz_scroll_warning = true;
|
||||
// console.log('Element is too wide for the container. Horizontal scrolling detected.');
|
||||
} else {
|
||||
horiz_scroll_warning = false;
|
||||
// console.log('Element fits within the container. No horizontal scrolling.', horiz_check_element);
|
||||
}
|
||||
});
|
||||
|
||||
function generate_file_export_csv(ae_obj_li: any[]) {
|
||||
console.log(`*** generate_file_export_csv() ***`, ae_obj_li);
|
||||
|
||||
// We need to create a list with the column names and then a list of lists with the data.
|
||||
let csv_data = [];
|
||||
let csv_columns = [
|
||||
'File ID',
|
||||
'Filename',
|
||||
'Extension',
|
||||
'Size',
|
||||
'SHA256 Hash',
|
||||
'Uploaded On',
|
||||
'Updated On',
|
||||
'Session ID',
|
||||
'Session Code',
|
||||
'Session Name',
|
||||
'Session Start Datetime',
|
||||
'Presentation ID',
|
||||
'Presentation Name',
|
||||
'Presentation Time',
|
||||
'Presenter ID',
|
||||
'Name',
|
||||
'Email',
|
||||
'Download Link',
|
||||
'Download Link - Session Code'
|
||||
];
|
||||
csv_data.push(csv_columns);
|
||||
|
||||
for (let i = 0; i < ae_obj_li.length; i++) {
|
||||
let csv_row = [];
|
||||
csv_row.push(ae_obj_li[i].event_file_id);
|
||||
csv_row.push(
|
||||
ae_obj_li[i].filename
|
||||
? `"${ae_util.clean_filename(ae_obj_li[i].filename)}"`
|
||||
: ''
|
||||
);
|
||||
csv_row.push(ae_obj_li[i].extension ? ae_obj_li[i].extension : '');
|
||||
csv_row.push(
|
||||
ae_obj_li[i].file_size || ae_obj_li[i].hosted_file_size
|
||||
? ae_util.format_bytes(
|
||||
ae_obj_li[i].file_size || ae_obj_li[i].hosted_file_size
|
||||
)
|
||||
: ''
|
||||
);
|
||||
csv_row.push(ae_obj_li[i].hash_sha256?.slice(0, 10) ?? 'N/A');
|
||||
csv_row.push(
|
||||
ae_obj_li[i].created_on
|
||||
? ae_util.iso_datetime_formatter(
|
||||
ae_obj_li[i].created_on,
|
||||
'datetime_iso_12_no_seconds'
|
||||
)
|
||||
: ''
|
||||
);
|
||||
csv_row.push(
|
||||
ae_obj_li[i].updated_on
|
||||
? ae_util.iso_datetime_formatter(
|
||||
ae_obj_li[i].updated_on,
|
||||
'datetime_iso_12_no_seconds'
|
||||
)
|
||||
: ''
|
||||
);
|
||||
|
||||
csv_row.push(
|
||||
ae_obj_li[i].event_session_id ? ae_obj_li[i].event_session_id : ''
|
||||
);
|
||||
csv_row.push(
|
||||
ae_obj_li[i].event_session_code
|
||||
? ae_obj_li[i].event_session_code
|
||||
: ''
|
||||
);
|
||||
csv_row.push(ae_obj_li[i].event_session_name ?? '');
|
||||
csv_row.push(
|
||||
ae_obj_li[i].event_session_start_datetime
|
||||
? ae_util.iso_datetime_formatter(
|
||||
ae_obj_li[i].event_session_start_datetime,
|
||||
'datetime_iso_12_no_seconds'
|
||||
)
|
||||
: ''
|
||||
);
|
||||
|
||||
csv_row.push(
|
||||
ae_obj_li[i].event_presentation_id
|
||||
? ae_obj_li[i].event_presentation_id
|
||||
: ''
|
||||
);
|
||||
csv_row.push(ae_obj_li[i].event_presentation_name ?? '');
|
||||
csv_row.push(
|
||||
ae_obj_li[i].event_presentation_start_datetime
|
||||
? ae_util.iso_datetime_formatter(
|
||||
ae_obj_li[i].event_presentation_start_datetime,
|
||||
'datetime_iso_12_no_seconds'
|
||||
)
|
||||
: ''
|
||||
);
|
||||
|
||||
csv_row.push(
|
||||
ae_obj_li[i].event_presenter_id
|
||||
? ae_obj_li[i].event_presenter_id
|
||||
: ''
|
||||
);
|
||||
csv_row.push(ae_obj_li[i].event_presenter_full_name ?? '');
|
||||
csv_row.push(
|
||||
ae_obj_li[i].event_presenter_email
|
||||
? ae_obj_li[i].event_presenter_email
|
||||
: ''
|
||||
);
|
||||
|
||||
csv_row.push(
|
||||
encodeURI(
|
||||
`${$ae_api.base_url}/event/file/${ae_obj_li[i]?.event_file_id}/download?filename=${ae_util.clean_filename(ae_obj_li[i]?.filename)}&key=${$ae_api.account_id}`
|
||||
)
|
||||
);
|
||||
|
||||
csv_row.push(
|
||||
encodeURI(
|
||||
`${$ae_api.base_url}/event/file/${ae_obj_li[i]?.event_file_id}/download?filename=${ae_obj_li[i]?.event_session_code}-${ae_util.clean_filename(ae_obj_li[i]?.filename)}&key=${$ae_api.account_id}`
|
||||
)
|
||||
);
|
||||
|
||||
csv_data.push(csv_row);
|
||||
}
|
||||
|
||||
// Check if element is scrolling horizontally
|
||||
$effect(() => {
|
||||
if (
|
||||
horiz_check_element &&
|
||||
horiz_check_element.scrollWidth > horiz_check_element.offsetWidth
|
||||
) {
|
||||
horiz_scroll_warning = true;
|
||||
// console.log('Element is too wide for the container. Horizontal scrolling detected.');
|
||||
} else {
|
||||
horiz_scroll_warning = false;
|
||||
// console.log('Element fits within the container. No horizontal scrolling.', horiz_check_element);
|
||||
}
|
||||
console.log('CSV Data:', csv_data);
|
||||
|
||||
let csv_content_str = '';
|
||||
csv_data.forEach(function (row) {
|
||||
csv_content_str += row.join(';');
|
||||
csv_content_str += '\n';
|
||||
});
|
||||
|
||||
function generate_file_export_csv(ae_obj_li: any[]) {
|
||||
console.log(`*** generate_file_export_csv() ***`, ae_obj_li);
|
||||
const blob = new Blob([csv_content_str], {
|
||||
type: 'text/csv;charset=utf-8;'
|
||||
});
|
||||
const obj_url = URL.createObjectURL(blob);
|
||||
|
||||
// We need to create a list with the column names and then a list of lists with the data.
|
||||
let csv_data = [];
|
||||
let csv_columns = [
|
||||
'File ID',
|
||||
'Filename',
|
||||
'Extension',
|
||||
'Size',
|
||||
'SHA256 Hash',
|
||||
'Uploaded On',
|
||||
'Updated On',
|
||||
'Session ID',
|
||||
'Session Code',
|
||||
'Session Name',
|
||||
'Session Start Datetime',
|
||||
'Presentation ID',
|
||||
'Presentation Name',
|
||||
'Presentation Time',
|
||||
'Presenter ID',
|
||||
'Name',
|
||||
'Email',
|
||||
'Download Link',
|
||||
'Download Link - Session Code'
|
||||
];
|
||||
csv_data.push(csv_columns);
|
||||
const download_link = document.createElement('a');
|
||||
download_link.setAttribute('href', obj_url);
|
||||
download_link.setAttribute(
|
||||
'download',
|
||||
`file_list_${ae_util.iso_datetime_formatter()}.csv`
|
||||
);
|
||||
download_link.setAttribute('style', 'display: none;');
|
||||
download_link.textContent = 'Download CSV';
|
||||
|
||||
for (let i = 0; i < ae_obj_li.length; i++) {
|
||||
let csv_row = [];
|
||||
csv_row.push(ae_obj_li[i].event_file_id);
|
||||
csv_row.push(
|
||||
ae_obj_li[i].filename
|
||||
? `"${ae_util.clean_filename(ae_obj_li[i].filename)}"`
|
||||
: ''
|
||||
);
|
||||
csv_row.push(ae_obj_li[i].extension ? ae_obj_li[i].extension : '');
|
||||
csv_row.push(
|
||||
ae_obj_li[i].file_size || ae_obj_li[i].hosted_file_size
|
||||
? ae_util.format_bytes(ae_obj_li[i].file_size || ae_obj_li[i].hosted_file_size)
|
||||
: ''
|
||||
);
|
||||
csv_row.push(ae_obj_li[i].hash_sha256?.slice(0, 10) ?? 'N/A');
|
||||
csv_row.push(
|
||||
ae_obj_li[i].created_on
|
||||
? ae_util.iso_datetime_formatter(
|
||||
ae_obj_li[i].created_on,
|
||||
'datetime_iso_12_no_seconds'
|
||||
)
|
||||
: ''
|
||||
);
|
||||
csv_row.push(
|
||||
ae_obj_li[i].updated_on
|
||||
? ae_util.iso_datetime_formatter(
|
||||
ae_obj_li[i].updated_on,
|
||||
'datetime_iso_12_no_seconds'
|
||||
)
|
||||
: ''
|
||||
);
|
||||
|
||||
csv_row.push(
|
||||
ae_obj_li[i].event_session_id
|
||||
? ae_obj_li[i].event_session_id
|
||||
: ''
|
||||
);
|
||||
csv_row.push(
|
||||
ae_obj_li[i].event_session_code
|
||||
? ae_obj_li[i].event_session_code
|
||||
: ''
|
||||
);
|
||||
csv_row.push(ae_obj_li[i].event_session_name ?? '');
|
||||
csv_row.push(
|
||||
ae_obj_li[i].event_session_start_datetime
|
||||
? ae_util.iso_datetime_formatter(
|
||||
ae_obj_li[i].event_session_start_datetime,
|
||||
'datetime_iso_12_no_seconds'
|
||||
)
|
||||
: ''
|
||||
);
|
||||
|
||||
csv_row.push(
|
||||
ae_obj_li[i].event_presentation_id
|
||||
? ae_obj_li[i].event_presentation_id
|
||||
: ''
|
||||
);
|
||||
csv_row.push(ae_obj_li[i].event_presentation_name ?? '');
|
||||
csv_row.push(
|
||||
ae_obj_li[i].event_presentation_start_datetime
|
||||
? ae_util.iso_datetime_formatter(
|
||||
ae_obj_li[i].event_presentation_start_datetime,
|
||||
'datetime_iso_12_no_seconds'
|
||||
)
|
||||
: ''
|
||||
);
|
||||
|
||||
csv_row.push(
|
||||
ae_obj_li[i].event_presenter_id
|
||||
? ae_obj_li[i].event_presenter_id
|
||||
: ''
|
||||
);
|
||||
csv_row.push(ae_obj_li[i].event_presenter_full_name ?? '');
|
||||
csv_row.push(
|
||||
ae_obj_li[i].event_presenter_email
|
||||
? ae_obj_li[i].event_presenter_email
|
||||
: ''
|
||||
);
|
||||
|
||||
csv_row.push(
|
||||
encodeURI(
|
||||
`${$ae_api.base_url}/event/file/${ae_obj_li[i]?.event_file_id}/download?filename=${ae_util.clean_filename(ae_obj_li[i]?.filename)}&key=${$ae_api.account_id}`
|
||||
)
|
||||
);
|
||||
|
||||
csv_row.push(
|
||||
encodeURI(
|
||||
`${$ae_api.base_url}/event/file/${ae_obj_li[i]?.event_file_id}/download?filename=${ae_obj_li[i]?.event_session_code}-${ae_util.clean_filename(ae_obj_li[i]?.filename)}&key=${$ae_api.account_id}`
|
||||
)
|
||||
);
|
||||
|
||||
csv_data.push(csv_row);
|
||||
}
|
||||
|
||||
console.log('CSV Data:', csv_data);
|
||||
|
||||
let csv_content_str = '';
|
||||
csv_data.forEach(function (row) {
|
||||
csv_content_str += row.join(';');
|
||||
csv_content_str += '\n';
|
||||
});
|
||||
|
||||
const blob = new Blob([csv_content_str], {
|
||||
type: 'text/csv;charset=utf-8;'
|
||||
});
|
||||
const obj_url = URL.createObjectURL(blob);
|
||||
|
||||
const download_link = document.createElement('a');
|
||||
download_link.setAttribute('href', obj_url);
|
||||
download_link.setAttribute(
|
||||
'download',
|
||||
`file_list_${ae_util.iso_datetime_formatter()}.csv`
|
||||
);
|
||||
download_link.setAttribute('style', 'display: none;');
|
||||
download_link.textContent = 'Download CSV';
|
||||
|
||||
const container = document.getElementById('download_csv_container');
|
||||
if (container) {
|
||||
container.appendChild(download_link);
|
||||
} else {
|
||||
document.body.appendChild(download_link);
|
||||
}
|
||||
|
||||
// Automatically download the file
|
||||
download_link.click();
|
||||
|
||||
return csv_data;
|
||||
const container = document.getElementById('download_csv_container');
|
||||
if (container) {
|
||||
container.appendChild(download_link);
|
||||
} else {
|
||||
document.body.appendChild(download_link);
|
||||
}
|
||||
|
||||
// Automatically download the file
|
||||
download_link.click();
|
||||
|
||||
return csv_data;
|
||||
}
|
||||
</script>
|
||||
|
||||
<section
|
||||
class:border-r-2={horiz_scroll_warning}
|
||||
class:border-dashed={horiz_scroll_warning}
|
||||
class:border-warning-900-100={horiz_scroll_warning}
|
||||
class="ae_comp event_file_obj_tbl {container_class_li} container overflow-auto max-w-screen"
|
||||
>
|
||||
class="ae_comp event_file_obj_tbl {container_class_li} container max-w-screen overflow-auto">
|
||||
<!-- {#if event_file_id_random_li && $lq_kv__event_file_obj_li && $lq_kv__event_file_obj_li?.length > 0 && $lq_kv__event_file_obj_li?.length == event_file_id_random_li?.length} -->
|
||||
{#if $lq__event_file_obj_li && $lq__event_file_obj_li?.length}
|
||||
<div
|
||||
bind:this={horiz_check_element}
|
||||
id="tbl_container"
|
||||
class="space-y-2 pb-8"
|
||||
>
|
||||
class="space-y-2 pb-8">
|
||||
<header
|
||||
class="flex flex-row flex-wrap gap-1 items-center justify-between"
|
||||
>
|
||||
class="flex flex-row flex-wrap items-center justify-between gap-1">
|
||||
<h2 class="h3">
|
||||
<span class="text-base"> Results: </span>
|
||||
|
||||
{#if $lq__event_file_obj_li.length}
|
||||
<span
|
||||
class="text-3xl font-bold preset-filled-success-100-900 px-4 rounded-lg"
|
||||
class="preset-filled-success-100-900 rounded-lg px-4 text-3xl font-bold"
|
||||
title="Count {$lq__event_file_obj_li.length ??
|
||||
'None'}"
|
||||
>
|
||||
'None'}">
|
||||
<ListOrdered size="1em" class="mx-4" />
|
||||
{$lq__event_file_obj_li.length ?? 'None'}×
|
||||
</span>
|
||||
@@ -316,12 +330,11 @@
|
||||
</h2>
|
||||
|
||||
<div
|
||||
class="flex flex-row flex-wrap gap-1 items-center justify-end"
|
||||
class:hidden={!$ae_loc.edit_mode}
|
||||
>
|
||||
class="flex flex-row flex-wrap items-center justify-end gap-1"
|
||||
class:hidden={!$ae_loc.edit_mode}>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-sm preset-tonal-warning border border-warning-500 mb-1 generate_csv_btn"
|
||||
class="btn btn-sm preset-tonal-warning border-warning-500 generate_csv_btn mb-1 border"
|
||||
onclick={() => {
|
||||
if (
|
||||
!confirm(
|
||||
@@ -335,8 +348,7 @@
|
||||
$lq__event_file_obj_li
|
||||
);
|
||||
console.log('CSV Data:', csv_data);
|
||||
}}
|
||||
>
|
||||
}}>
|
||||
<FileSpreadsheet size="1em" class="mx-1" />
|
||||
Export Files CSV
|
||||
</button>
|
||||
@@ -351,8 +363,7 @@
|
||||
class="btn btn-sm {show_session_fields
|
||||
? 'ae_btn_surface'
|
||||
: 'ae_btn_surface_outlined'}"
|
||||
title="Show or hide the session-related column fields."
|
||||
>
|
||||
title="Show or hide the session-related column fields.">
|
||||
<ToggleRight size="1em" class="m-1" />
|
||||
Showing Session Fields
|
||||
</button>
|
||||
@@ -365,8 +376,7 @@
|
||||
class="btn btn-sm {show_session_fields
|
||||
? 'ae_btn_surface'
|
||||
: 'ae_btn_surface_outlined'}"
|
||||
title="Show or hide the session-related column fields."
|
||||
>
|
||||
title="Show or hide the session-related column fields.">
|
||||
<ToggleLeft size="1em" class="m-1" />
|
||||
Show Session Fields
|
||||
</button>
|
||||
@@ -380,8 +390,7 @@
|
||||
hide_session_code = true;
|
||||
}}
|
||||
class="btn btn-sm ae_btn_surface"
|
||||
title="Hide the session code column from view. Currently showing the Session Code column."
|
||||
>
|
||||
title="Hide the session code column from view. Currently showing the Session Code column.">
|
||||
<ToggleRight size="1em" class="m-1" />
|
||||
Showing Session Code
|
||||
</button>
|
||||
@@ -392,8 +401,7 @@
|
||||
hide_session_code = false;
|
||||
}}
|
||||
class="btn btn-sm ae_btn_surface_outlined"
|
||||
title="Show the session code column. Currently hiding the Session Code column from view."
|
||||
>
|
||||
title="Show the session code column. Currently hiding the Session Code column from view.">
|
||||
<ToggleLeft size="1em" class="m-1" />
|
||||
Show Session Code
|
||||
</button>
|
||||
@@ -409,8 +417,7 @@
|
||||
class="btn btn-sm {show_presentation_fields
|
||||
? 'ae_btn_surface'
|
||||
: 'ae_btn_surface_outlined'}"
|
||||
title="Show or hide the extra presentation-related column fields."
|
||||
>
|
||||
title="Show or hide the extra presentation-related column fields.">
|
||||
<ToggleRight size="1em" class="m-1" />
|
||||
Showing Presentation Fields
|
||||
</button>
|
||||
@@ -424,8 +431,7 @@
|
||||
class="btn btn-sm {show_presentation_fields
|
||||
? 'ae_btn_surface'
|
||||
: 'ae_btn_surface_outlined'}"
|
||||
title="Show or hide the extra presentation-related column fields."
|
||||
>
|
||||
title="Show or hide the extra presentation-related column fields.">
|
||||
<ToggleLeft size="1em" class="m-1" />
|
||||
Show Presentation Fields
|
||||
</button>
|
||||
@@ -434,8 +440,7 @@
|
||||
</header>
|
||||
|
||||
<table
|
||||
class="table table-auto table-striped w-full text-xs lg:text-sm"
|
||||
>
|
||||
class="table-striped table w-full table-auto text-xs lg:text-sm">
|
||||
<thead class="">
|
||||
<tr>
|
||||
<th class="px-4 py-2">
|
||||
@@ -444,8 +449,7 @@
|
||||
</th>
|
||||
<th
|
||||
class="px-4 py-2"
|
||||
class:hidden={!show_direct_download}
|
||||
>
|
||||
class:hidden={!show_direct_download}>
|
||||
Link
|
||||
</th>
|
||||
<th class="px-4 py-2">Size</th>
|
||||
@@ -456,8 +460,7 @@
|
||||
{#if show_session_fields}
|
||||
<th
|
||||
class="px-4 py-2"
|
||||
class:hidden={hide_session_code}
|
||||
>
|
||||
class:hidden={hide_session_code}>
|
||||
Code
|
||||
</th>
|
||||
<th class="px-4 py-2"> Session </th>
|
||||
@@ -482,41 +485,58 @@
|
||||
show_divider={true}
|
||||
{show_direct_download}
|
||||
max_filename={50}
|
||||
classes="btn btn-sm preset-tonal-primary hover:preset-filled-primary-500 min-w-72"
|
||||
/>
|
||||
classes="btn btn-sm preset-tonal-primary hover:preset-filled-primary-500 min-w-72" />
|
||||
<!-- PDF → webp convert button: only for poster sessions in edit mode -->
|
||||
{#if $ae_loc.edit_mode && event_file_obj?.extension === 'pdf' && event_file_obj?.event_session_type_code === 'poster'}
|
||||
<div class="mt-1">
|
||||
{#if !convert_status_kv[event_file_obj.event_file_id] || convert_status_kv[event_file_obj.event_file_id] === 'idle'}
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-sm preset-tonal-warning border border-warning-500"
|
||||
class="btn btn-sm preset-tonal-warning border-warning-500 border"
|
||||
title="Convert this PDF to a high-res webp image for use in the Launcher poster display."
|
||||
onclick={() => handle_convert_pdf_to_image(event_file_obj)}
|
||||
>
|
||||
<FileImage size="1em" class="mx-1" />
|
||||
onclick={() =>
|
||||
handle_convert_pdf_to_image(
|
||||
event_file_obj
|
||||
)}>
|
||||
<FileImage
|
||||
size="1em"
|
||||
class="mx-1" />
|
||||
Convert PDF → Image
|
||||
</button>
|
||||
{:else if convert_status_kv[event_file_obj.event_file_id] === 'converting'}
|
||||
<span class="btn btn-sm preset-tonal-surface opacity-60 cursor-wait">
|
||||
<LoaderCircle size="1em" class="mx-1 animate-spin" />
|
||||
<span
|
||||
class="btn btn-sm preset-tonal-surface cursor-wait opacity-60">
|
||||
<LoaderCircle
|
||||
size="1em"
|
||||
class="mx-1 animate-spin" />
|
||||
Converting…
|
||||
</span>
|
||||
{:else if convert_status_kv[event_file_obj.event_file_id] === 'done'}
|
||||
<span class="btn btn-sm preset-tonal-success" title="Conversion complete. New webp hosted_file created: {convert_result_kv[event_file_obj.event_file_id]?.filename ?? ''}">
|
||||
<Check size="1em" class="mx-1" />
|
||||
Done — {convert_result_kv[event_file_obj.event_file_id]?.filename ?? 'image created'}
|
||||
<span
|
||||
class="btn btn-sm preset-tonal-success"
|
||||
title="Conversion complete. New webp hosted_file created: {convert_result_kv[
|
||||
event_file_obj.event_file_id
|
||||
]?.filename ?? ''}">
|
||||
<Check
|
||||
size="1em"
|
||||
class="mx-1" />
|
||||
Done — {convert_result_kv[
|
||||
event_file_obj.event_file_id
|
||||
]?.filename ?? 'image created'}
|
||||
</span>
|
||||
{:else if convert_status_kv[event_file_obj.event_file_id] === 'error'}
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-sm preset-tonal-error border border-error-500"
|
||||
class="btn btn-sm preset-tonal-error border-error-500 border"
|
||||
title="Conversion failed. Click to retry."
|
||||
onclick={() => {
|
||||
convert_status_kv[event_file_obj.event_file_id] = 'idle';
|
||||
}}
|
||||
>
|
||||
<TriangleAlert size="1em" class="mx-1" />
|
||||
convert_status_kv[
|
||||
event_file_obj.event_file_id
|
||||
] = 'idle';
|
||||
}}>
|
||||
<TriangleAlert
|
||||
size="1em"
|
||||
class="mx-1" />
|
||||
Failed — Retry?
|
||||
</button>
|
||||
{/if}
|
||||
@@ -524,23 +544,20 @@
|
||||
{/if}
|
||||
</td>
|
||||
<td
|
||||
class="px-4 py-2 flex flex-col gap-0.5"
|
||||
class:hidden={!show_direct_download}
|
||||
>
|
||||
class="flex flex-col gap-0.5 px-4 py-2"
|
||||
class:hidden={!show_direct_download}>
|
||||
<div
|
||||
class:hidden={!show_direct_download}
|
||||
class="flex flex-row gap-0.5"
|
||||
>
|
||||
<span class="text-xs text-gray-500 w-32">
|
||||
class="flex flex-row gap-0.5">
|
||||
<span class="w-32 text-xs text-gray-500">
|
||||
Original:
|
||||
</span>
|
||||
<a
|
||||
href="{$ae_api.base_url}/event/file/{event_file_obj?.event_file_id}/download?filename={ae_util.clean_filename(
|
||||
event_file_obj?.filename
|
||||
)}&key={$ae_api.account_id}"
|
||||
class="btn btn-sm p-1 preset-tonal-secondary *:hover:inline lg:text-xs underline"
|
||||
title={`Download this file:\n${ae_util.clean_filename(event_file_obj?.filename)}\n[API] SHA256: ${event_file_obj?.hash_sha256?.slice(0, 10) ?? 'N/A'}\nHosted ID: ${event_file_obj?.hosted_file_id} Event File ID: ${event_file_obj?.event_file_id}`}
|
||||
>
|
||||
class="btn btn-sm preset-tonal-secondary p-1 underline *:hover:inline lg:text-xs"
|
||||
title={`Download this file:\n${ae_util.clean_filename(event_file_obj?.filename)}\n[API] SHA256: ${event_file_obj?.hash_sha256?.slice(0, 10) ?? 'N/A'}\nHosted ID: ${event_file_obj?.hosted_file_id} Event File ID: ${event_file_obj?.event_file_id}`}>
|
||||
<Download size="1em" class="mx-1" />
|
||||
<span class="hidden"> Download </span>
|
||||
</a>
|
||||
@@ -560,9 +577,8 @@
|
||||
|
||||
<div
|
||||
class="flex flex-row gap-0.5"
|
||||
class:hidden={!show_direct_download}
|
||||
>
|
||||
<span class="text-xs text-gray-500 w-32">
|
||||
class:hidden={!show_direct_download}>
|
||||
<span class="w-32 text-xs text-gray-500">
|
||||
Session Name:
|
||||
</span>
|
||||
<a
|
||||
@@ -576,9 +592,8 @@
|
||||
)}-{ae_util.clean_filename(
|
||||
event_file_obj?.event_presenter_full_name
|
||||
)}.{event_file_obj?.extension}&key={$ae_api.account_id}"
|
||||
class="btn btn-sm p-1 preset-tonal-secondary *:hover:inline lg:text-xs underline"
|
||||
title={`Download renamed with session name to: ${event_file_obj?.event_session_code}-${ae_util.clean_filename(event_file_obj?.event_session_name).substring(0, 20)}-${ae_util.clean_filename(event_file_obj?.event_presenter_full_name)}.${event_file_obj?.extension}`}
|
||||
>
|
||||
class="btn btn-sm preset-tonal-secondary p-1 underline *:hover:inline lg:text-xs"
|
||||
title={`Download renamed with session name to: ${event_file_obj?.event_session_code}-${ae_util.clean_filename(event_file_obj?.event_session_name).substring(0, 20)}-${ae_util.clean_filename(event_file_obj?.event_presenter_full_name)}.${event_file_obj?.extension}`}>
|
||||
<Download size="1em" class="mx-1" />
|
||||
<span class="hidden"> Renamed </span>
|
||||
</a>
|
||||
@@ -595,9 +610,8 @@
|
||||
|
||||
<div
|
||||
class:hidden={!show_direct_download}
|
||||
class="flex flex-row gap-0.5"
|
||||
>
|
||||
<span class="text-xs text-gray-500 w-32">
|
||||
class="flex flex-row gap-0.5">
|
||||
<span class="w-32 text-xs text-gray-500">
|
||||
Presentation Name:
|
||||
</span>
|
||||
<a
|
||||
@@ -611,9 +625,8 @@
|
||||
)}-{ae_util.clean_filename(
|
||||
event_file_obj?.event_presenter_full_name
|
||||
)}.{event_file_obj?.extension}&key=${$ae_api.account_id}"
|
||||
class="btn btn-sm p-1 preset-tonal-secondary *:hover:inline lg:text-xs underline"
|
||||
title={`Download renamed with presentation name to: ${event_file_obj?.event_session_code}-${ae_util.clean_filename(event_file_obj?.event_presentation_name).substring(0, 20)}-${ae_util.clean_filename(event_file_obj?.event_presenter_full_name)}.${event_file_obj?.extension}`}
|
||||
>
|
||||
class="btn btn-sm preset-tonal-secondary p-1 underline *:hover:inline lg:text-xs"
|
||||
title={`Download renamed with presentation name to: ${event_file_obj?.event_session_code}-${ae_util.clean_filename(event_file_obj?.event_presentation_name).substring(0, 20)}-${ae_util.clean_filename(event_file_obj?.event_presenter_full_name)}.${event_file_obj?.extension}`}>
|
||||
<Download size="1em" class="mx-1" />
|
||||
<span class="hidden"> Renamed </span>
|
||||
</a>
|
||||
@@ -630,9 +643,9 @@
|
||||
</td>
|
||||
<td class="px-4 py-2"
|
||||
>{ae_util.format_bytes(
|
||||
event_file_obj?.file_size || event_file_obj?.hosted_file_size
|
||||
)}</td
|
||||
>
|
||||
event_file_obj?.file_size ||
|
||||
event_file_obj?.hosted_file_size
|
||||
)}</td>
|
||||
<td class="px-4 py-2">
|
||||
<div>
|
||||
<span>
|
||||
@@ -669,8 +682,7 @@
|
||||
event_file_obj?.created_on,
|
||||
minutes: 2880
|
||||
}
|
||||
)}
|
||||
>
|
||||
)}>
|
||||
{ae_util.iso_datetime_formatter(
|
||||
event_file_obj?.created_on,
|
||||
'time_12_short'
|
||||
@@ -691,8 +703,7 @@
|
||||
{#if show_session_fields}
|
||||
<td
|
||||
class="px-4 py-2 lg:text-xs"
|
||||
class:hidden={hide_session_code}
|
||||
>
|
||||
class:hidden={hide_session_code}>
|
||||
{event_file_obj?.event_session_code ??
|
||||
'-- not set --'}
|
||||
</td>
|
||||
@@ -700,8 +711,7 @@
|
||||
<Presentation size="1em" />
|
||||
<a
|
||||
href="/events/{event_file_obj?.event_id}/session/{event_file_obj?.event_session_id}"
|
||||
class="text-blue-500 underline hover:text-blue-800"
|
||||
>
|
||||
class="text-blue-500 underline hover:text-blue-800">
|
||||
{event_file_obj?.event_session_name}
|
||||
</a>
|
||||
</td>
|
||||
@@ -709,8 +719,7 @@
|
||||
>{ae_util.iso_datetime_formatter(
|
||||
event_file_obj?.event_session_start_datetime,
|
||||
'datetime_iso_12_no_seconds'
|
||||
)}</td
|
||||
>
|
||||
)}</td>
|
||||
{/if}
|
||||
{#if show_presentation_fields}
|
||||
<td class="px-4 py-2 lg:text-xs">
|
||||
@@ -736,8 +745,7 @@
|
||||
<User size="1em" />
|
||||
<a
|
||||
href="/events/{event_file_obj?.event_id}/presenter/{event_file_obj?.event_presenter_id}"
|
||||
class="text-blue-500 underline hover:text-blue-800"
|
||||
>
|
||||
class="text-blue-500 underline hover:text-blue-800">
|
||||
{event_file_obj?.event_presenter_full_name}
|
||||
</a>
|
||||
{:else}
|
||||
@@ -745,7 +753,6 @@
|
||||
{@html ae_snip.html__not_set}
|
||||
{/if}
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
@@ -757,8 +764,8 @@
|
||||
</section>
|
||||
|
||||
<style>
|
||||
.dim {
|
||||
opacity: 0.5;
|
||||
color: #999;
|
||||
}
|
||||
.dim {
|
||||
opacity: 0.5;
|
||||
color: #999;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,124 +1,124 @@
|
||||
<script lang="ts">
|
||||
interface Props {
|
||||
// Exports
|
||||
container_class_li?: string | Array<string>;
|
||||
event_file_obj_li?: Array<any>;
|
||||
link_to_type?: string;
|
||||
link_to_id?: string;
|
||||
allow_basic?: boolean;
|
||||
allow_moderator?: boolean;
|
||||
show_direct_download?: boolean;
|
||||
show_location_fields?: boolean;
|
||||
show_presentation_fields?: boolean;
|
||||
show_session_fields?: boolean;
|
||||
hide_session_code?: boolean;
|
||||
log_lvl?: number;
|
||||
interface Props {
|
||||
// Exports
|
||||
container_class_li?: string | Array<string>;
|
||||
event_file_obj_li?: Array<any>;
|
||||
link_to_type?: string;
|
||||
link_to_id?: string;
|
||||
allow_basic?: boolean;
|
||||
allow_moderator?: boolean;
|
||||
show_direct_download?: boolean;
|
||||
show_location_fields?: boolean;
|
||||
show_presentation_fields?: boolean;
|
||||
show_session_fields?: boolean;
|
||||
hide_session_code?: boolean;
|
||||
log_lvl?: number;
|
||||
}
|
||||
|
||||
let {
|
||||
container_class_li = [],
|
||||
// display_mode = 'default',
|
||||
// event_file_id_random_li = $bindable(),
|
||||
event_file_obj_li = $bindable(),
|
||||
link_to_type,
|
||||
link_to_id,
|
||||
allow_basic = true,
|
||||
allow_moderator = true,
|
||||
show_direct_download = $bindable(false),
|
||||
show_location_fields = false,
|
||||
show_presentation_fields = true,
|
||||
show_session_fields = true,
|
||||
hide_session_code = false,
|
||||
log_lvl = $bindable(0)
|
||||
}: Props = $props();
|
||||
|
||||
// Imports
|
||||
import Comp_event_file_obj_tbl from './ae_comp__event_file_obj_tbl.svelte';
|
||||
|
||||
import { liveQuery } from 'dexie';
|
||||
import {
|
||||
events_loc,
|
||||
events_sess,
|
||||
events_slct,
|
||||
events_trigger
|
||||
} from '$lib/stores/ae_events_stores';
|
||||
import { db_events } from '$lib/ae_events/db_events';
|
||||
|
||||
$effect(() => {
|
||||
if (log_lvl) {
|
||||
console.log(`link_to_type: ${link_to_type}; link_to_id: ${link_to_id}`);
|
||||
}
|
||||
});
|
||||
|
||||
let {
|
||||
container_class_li = [],
|
||||
// display_mode = 'default',
|
||||
// event_file_id_random_li = $bindable(),
|
||||
event_file_obj_li = $bindable(),
|
||||
link_to_type,
|
||||
link_to_id,
|
||||
allow_basic = true,
|
||||
allow_moderator = true,
|
||||
show_direct_download = $bindable(false),
|
||||
show_location_fields = false,
|
||||
show_presentation_fields = true,
|
||||
show_session_fields = true,
|
||||
hide_session_code = false,
|
||||
log_lvl = $bindable(0)
|
||||
}: Props = $props();
|
||||
// Variables
|
||||
// let ae_promises: key_val = {};
|
||||
// let ae_tmp: key_val = {};
|
||||
// let ae_triggers: key_val = {};
|
||||
|
||||
// Imports
|
||||
import Comp_event_file_obj_tbl from './ae_comp__event_file_obj_tbl.svelte';
|
||||
let event_file_id_random_li: Array<string> = $state([]);
|
||||
|
||||
import { liveQuery } from 'dexie';
|
||||
import {
|
||||
events_loc,
|
||||
events_sess,
|
||||
events_slct,
|
||||
events_trigger
|
||||
} from '$lib/stores/ae_events_stores';
|
||||
import { db_events } from '$lib/ae_events/db_events';
|
||||
let dq__where_type_id_val = $derived(`${link_to_type}_id_random`);
|
||||
let dq__where_eq_id_val = $derived(link_to_id ?? '');
|
||||
|
||||
$effect(() => {
|
||||
if (log_lvl) {
|
||||
console.log(`link_to_type: ${link_to_type}; link_to_id: ${link_to_id}`);
|
||||
// *** Functions and Logic
|
||||
|
||||
// OPTIMIZATION: If event_file_obj_li is provided (from API/reports),
|
||||
// use it directly instead of fetching from IDB. The API returns fully
|
||||
// enriched data with all joined fields (session names, presentation names, etc.)
|
||||
// that aren't available in the base IDB file table.
|
||||
let lq__event_file_obj_li = $derived(
|
||||
liveQuery(async () => {
|
||||
let results: any;
|
||||
|
||||
// If data is already provided (from API reports with joins), use it directly
|
||||
if (event_file_obj_li?.length) {
|
||||
if (log_lvl) {
|
||||
console.log(
|
||||
`LQ - Using provided event_file_obj_li (${event_file_obj_li.length} files with API joins)`
|
||||
);
|
||||
}
|
||||
return event_file_obj_li;
|
||||
}
|
||||
});
|
||||
|
||||
// Variables
|
||||
// let ae_promises: key_val = {};
|
||||
// let ae_tmp: key_val = {};
|
||||
// let ae_triggers: key_val = {};
|
||||
|
||||
let event_file_id_random_li: Array<string> = $state([]);
|
||||
|
||||
let dq__where_type_id_val = $derived(`${link_to_type}_id_random`);
|
||||
let dq__where_eq_id_val = $derived(link_to_id ?? '');
|
||||
|
||||
// *** Functions and Logic
|
||||
|
||||
// OPTIMIZATION: If event_file_obj_li is provided (from API/reports),
|
||||
// use it directly instead of fetching from IDB. The API returns fully
|
||||
// enriched data with all joined fields (session names, presentation names, etc.)
|
||||
// that aren't available in the base IDB file table.
|
||||
let lq__event_file_obj_li = $derived(
|
||||
liveQuery(async () => {
|
||||
let results: any;
|
||||
|
||||
// If data is already provided (from API reports with joins), use it directly
|
||||
if (event_file_obj_li?.length) {
|
||||
if (log_lvl) {
|
||||
console.log(
|
||||
`LQ - Using provided event_file_obj_li (${event_file_obj_li.length} files with API joins)`
|
||||
);
|
||||
}
|
||||
return event_file_obj_li;
|
||||
// Otherwise fetch from IDB for link_to_type/link_to_id lookups
|
||||
if (link_to_type && link_to_id) {
|
||||
if (log_lvl) {
|
||||
console.log(
|
||||
`LQ - Fetching from IDB where: ${dq__where_type_id_val} = ${dq__where_eq_id_val}`
|
||||
);
|
||||
}
|
||||
results = await db_events.file
|
||||
.where(dq__where_type_id_val)
|
||||
.equals(dq__where_eq_id_val)
|
||||
.sortBy('name');
|
||||
} else {
|
||||
results = [];
|
||||
}
|
||||
|
||||
// Otherwise fetch from IDB for link_to_type/link_to_id lookups
|
||||
if (link_to_type && link_to_id) {
|
||||
if (log_lvl) {
|
||||
console.log(
|
||||
`LQ - Fetching from IDB where: ${dq__where_type_id_val} = ${dq__where_eq_id_val}`
|
||||
);
|
||||
}
|
||||
results = await db_events.file
|
||||
.where(dq__where_type_id_val)
|
||||
.equals(dq__where_eq_id_val)
|
||||
.sortBy('name');
|
||||
} else {
|
||||
results = [];
|
||||
// Check if results are different than the current session version stored under $events_slct
|
||||
if (
|
||||
$events_slct.event_file_obj_li &&
|
||||
JSON.stringify($events_slct.event_file_obj_li) !==
|
||||
JSON.stringify(results)
|
||||
) {
|
||||
$events_slct.event_file_obj_li = [...results];
|
||||
if (log_lvl) {
|
||||
console.log(
|
||||
`Session slct li stored version has changed for ID = ${$events_slct.journal_id}`,
|
||||
$events_slct.event_file_obj_li
|
||||
);
|
||||
}
|
||||
|
||||
// Check if results are different than the current session version stored under $events_slct
|
||||
if (
|
||||
$events_slct.event_file_obj_li &&
|
||||
JSON.stringify($events_slct.event_file_obj_li) !==
|
||||
JSON.stringify(results)
|
||||
) {
|
||||
$events_slct.event_file_obj_li = [...results];
|
||||
if (log_lvl) {
|
||||
console.log(
|
||||
`Session slct li stored version has changed for ID = ${$events_slct.journal_id}`,
|
||||
$events_slct.event_file_obj_li
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if (log_lvl > 1) {
|
||||
console.log(
|
||||
`Session slct li stored version has not changed for ID = ${$events_slct.journal_id}`
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if (log_lvl > 1) {
|
||||
console.log(
|
||||
`Session slct li stored version has not changed for ID = ${$events_slct.journal_id}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
})
|
||||
);
|
||||
return results;
|
||||
})
|
||||
);
|
||||
</script>
|
||||
|
||||
{#if event_file_obj_li && event_file_obj_li?.length}
|
||||
@@ -132,10 +132,9 @@
|
||||
{show_presentation_fields}
|
||||
{show_session_fields}
|
||||
{hide_session_code}
|
||||
{log_lvl}
|
||||
></Comp_event_file_obj_tbl>
|
||||
{log_lvl}></Comp_event_file_obj_tbl>
|
||||
{:else}
|
||||
<section class="grow px-1 md:px-2 pb-28 flex flex-col gap-1 items-center">
|
||||
<section class="flex grow flex-col items-center gap-1 px-1 pb-28 md:px-2">
|
||||
<p>No files available to show in table.</p>
|
||||
</section>
|
||||
{/if}
|
||||
|
||||
@@ -1,206 +1,203 @@
|
||||
<script lang="ts">
|
||||
/**
|
||||
* src/routes/events/ae_comp__event_files_upload.svelte
|
||||
* Specialized component for uploading files and automatically linking them to Event objects.
|
||||
*/
|
||||
import { LoaderCircle, Upload, UploadCloud } from '@lucide/svelte';
|
||||
import Element_input_files_tbl from '$lib/elements/element_input_files_tbl.svelte';
|
||||
/**
|
||||
* src/routes/events/ae_comp__event_files_upload.svelte
|
||||
* Specialized component for uploading files and automatically linking them to Event objects.
|
||||
*/
|
||||
import { LoaderCircle, Upload, UploadCloud } from '@lucide/svelte';
|
||||
import Element_input_files_tbl from '$lib/elements/element_input_files_tbl.svelte';
|
||||
|
||||
// Import storage, functions, and libraries
|
||||
import type { key_val } from '$lib/stores/ae_stores';
|
||||
import { api } from '$lib/api/api';
|
||||
import {
|
||||
ae_loc,
|
||||
ae_sess,
|
||||
ae_api,
|
||||
ae_trig,
|
||||
slct,
|
||||
slct_trigger
|
||||
} from '$lib/stores/ae_stores';
|
||||
import {
|
||||
events_loc,
|
||||
events_sess,
|
||||
events_slct,
|
||||
events_trig
|
||||
} from '$lib/stores/ae_events_stores';
|
||||
import { events_func } from '$lib/ae_events/ae_events_functions';
|
||||
import { db_events } from '$lib/ae_events/db_events';
|
||||
// Import storage, functions, and libraries
|
||||
import type { key_val } from '$lib/stores/ae_stores';
|
||||
import { api } from '$lib/api/api';
|
||||
import {
|
||||
ae_loc,
|
||||
ae_sess,
|
||||
ae_api,
|
||||
ae_trig,
|
||||
slct,
|
||||
slct_trigger
|
||||
} from '$lib/stores/ae_stores';
|
||||
import {
|
||||
events_loc,
|
||||
events_sess,
|
||||
events_slct,
|
||||
events_trig
|
||||
} from '$lib/stores/ae_events_stores';
|
||||
import { events_func } from '$lib/ae_events/ae_events_functions';
|
||||
import { db_events } from '$lib/ae_events/db_events';
|
||||
|
||||
interface Props {
|
||||
log_lvl?: number;
|
||||
// Expecting these for link_to_type: 'event', 'event_location', 'event_presentation', 'event_presenter', 'event_session'
|
||||
link_to_type: string;
|
||||
link_to_id: string;
|
||||
input_name?: string;
|
||||
multiple?: boolean;
|
||||
required?: boolean;
|
||||
accept?: string;
|
||||
class_li_default?: string;
|
||||
class_li?: string;
|
||||
input_class_li?: string[];
|
||||
table_class_li?: string[];
|
||||
upload_complete?: boolean;
|
||||
submit_status?: null | string;
|
||||
label?: import('svelte').Snippet;
|
||||
interface Props {
|
||||
log_lvl?: number;
|
||||
// Expecting these for link_to_type: 'event', 'event_location', 'event_presentation', 'event_presenter', 'event_session'
|
||||
link_to_type: string;
|
||||
link_to_id: string;
|
||||
input_name?: string;
|
||||
multiple?: boolean;
|
||||
required?: boolean;
|
||||
accept?: string;
|
||||
class_li_default?: string;
|
||||
class_li?: string;
|
||||
input_class_li?: string[];
|
||||
table_class_li?: string[];
|
||||
upload_complete?: boolean;
|
||||
submit_status?: null | string;
|
||||
label?: import('svelte').Snippet;
|
||||
}
|
||||
|
||||
let {
|
||||
log_lvl = $bindable(0),
|
||||
link_to_type,
|
||||
link_to_id,
|
||||
input_name = 'file_list',
|
||||
multiple = true,
|
||||
required = true,
|
||||
accept = 'audio/*, image/*, video/*, .bak, .cfg, .css, .csv, .doc, .docx, .gz, .htm, .html, .ini, .iso, .j2, .json, .key, .keynote, .md, .pdf, .ppt, .pptx, .rar, .rtf, .sql, .svelte, ttf, .txt, .xls, .xlsx, .xz, .zip, .bin, .dmg, .exe, .js, .msi, .php, .py, .sh',
|
||||
class_li_default = 'flex flex-col gap-1 items-center justify-center w-full max-w-2xl mx-auto my-1',
|
||||
class_li = '',
|
||||
input_class_li = ['file_drop_area'],
|
||||
table_class_li = ['table', 'table-sm', 'table-striped', '', 'text-sm'],
|
||||
upload_complete = $bindable(false),
|
||||
submit_status = $bindable(null),
|
||||
label
|
||||
}: Props = $props();
|
||||
|
||||
// Local Variables
|
||||
let task_id: string = $state('');
|
||||
let input_file_list: any = $state(null);
|
||||
let ae_promises: key_val = $state({});
|
||||
let input_element_id = 'ae_comp__event_files_upload__input';
|
||||
|
||||
// WHY: Keep task_id in sync with prop if it hasn't been set by an upload cycle yet
|
||||
$effect(() => {
|
||||
if (!ae_promises.upload__hosted_file_obj) {
|
||||
task_id = link_to_id;
|
||||
}
|
||||
});
|
||||
|
||||
let {
|
||||
log_lvl = $bindable(0),
|
||||
link_to_type,
|
||||
link_to_id,
|
||||
input_name = 'file_list',
|
||||
multiple = true,
|
||||
required = true,
|
||||
accept = 'audio/*, image/*, video/*, .bak, .cfg, .css, .csv, .doc, .docx, .gz, .htm, .html, .ini, .iso, .j2, .json, .key, .keynote, .md, .pdf, .ppt, .pptx, .rar, .rtf, .sql, .svelte, ttf, .txt, .xls, .xlsx, .xz, .zip, .bin, .dmg, .exe, .js, .msi, .php, .py, .sh',
|
||||
class_li_default = 'flex flex-col gap-1 items-center justify-center w-full max-w-2xl mx-auto my-1',
|
||||
class_li = '',
|
||||
input_class_li = ['file_drop_area'],
|
||||
table_class_li = ['table', 'table-sm', 'table-striped', '', 'text-sm'],
|
||||
upload_complete = $bindable(false),
|
||||
submit_status = $bindable(null),
|
||||
label
|
||||
}: Props = $props();
|
||||
function prevent_default<T extends Event>(fn: (event: T) => void) {
|
||||
return function (event: T) {
|
||||
event.preventDefault();
|
||||
fn(event);
|
||||
};
|
||||
}
|
||||
|
||||
// Local Variables
|
||||
let task_id: string = $state('');
|
||||
let input_file_list: any = $state(null);
|
||||
let ae_promises: key_val = $state({});
|
||||
let input_element_id = 'ae_comp__event_files_upload__input';
|
||||
async function handle_submit_form_files(event: SubmitEvent) {
|
||||
if (log_lvl) console.log('*** handle_submit_form() ***');
|
||||
|
||||
// WHY: Keep task_id in sync with prop if it hasn't been set by an upload cycle yet
|
||||
$effect(() => {
|
||||
if (!ae_promises.upload__hosted_file_obj) {
|
||||
task_id = link_to_id;
|
||||
}
|
||||
});
|
||||
$events_sess.files.disable_submit__event_file_obj = true;
|
||||
$events_sess.files.submit_status = 'saving';
|
||||
submit_status = 'saving';
|
||||
upload_complete = false;
|
||||
|
||||
function prevent_default<T extends Event>(fn: (event: T) => void) {
|
||||
return function (event: T) {
|
||||
event.preventDefault();
|
||||
fn(event);
|
||||
};
|
||||
}
|
||||
const target = event.currentTarget as HTMLFormElement;
|
||||
const file_input = target
|
||||
? (target[input_element_id] as HTMLInputElement)
|
||||
: null;
|
||||
|
||||
async function handle_submit_form_files(event: SubmitEvent) {
|
||||
if (log_lvl) console.log('*** handle_submit_form() ***');
|
||||
if (file_input && file_input.files && file_input.files.length > 0) {
|
||||
// Sequential upload to provide reliable progress and avoid server race conditions
|
||||
for (let i = 0; i < file_input.files.length; i++) {
|
||||
const tmp_file = file_input.files[i];
|
||||
task_id = $events_sess.files.processed_file_list[i].hash_sha256;
|
||||
|
||||
$events_sess.files.disable_submit__event_file_obj = true;
|
||||
$events_sess.files.submit_status = 'saving';
|
||||
submit_status = 'saving';
|
||||
upload_complete = false;
|
||||
|
||||
const target = event.currentTarget as HTMLFormElement;
|
||||
const file_input = target
|
||||
? (target[input_element_id] as HTMLInputElement)
|
||||
: null;
|
||||
|
||||
if (file_input && file_input.files && file_input.files.length > 0) {
|
||||
// Sequential upload to provide reliable progress and avoid server race conditions
|
||||
for (let i = 0; i < file_input.files.length; i++) {
|
||||
const tmp_file = file_input.files[i];
|
||||
task_id = $events_sess.files.processed_file_list[i].hash_sha256;
|
||||
|
||||
await handle_input_upload_files({
|
||||
input_upload_files: [tmp_file],
|
||||
task_id: task_id
|
||||
});
|
||||
}
|
||||
|
||||
// Cleanup after batch
|
||||
$events_sess.files.processed_file_list = [];
|
||||
target.reset();
|
||||
|
||||
// Refresh Local Cache (Optimistic Revalidation)
|
||||
await db_events.file.clear();
|
||||
events_func.load_ae_obj_li__event_file({
|
||||
api_cfg: $ae_api,
|
||||
for_obj_type: link_to_type,
|
||||
for_obj_id: link_to_id,
|
||||
enabled: 'all',
|
||||
hidden: 'all',
|
||||
try_cache: true
|
||||
await handle_input_upload_files({
|
||||
input_upload_files: [tmp_file],
|
||||
task_id: task_id
|
||||
});
|
||||
}
|
||||
|
||||
$events_sess.files.disable_submit__event_file_obj = false;
|
||||
$events_sess.files.submit_status = 'saved';
|
||||
submit_status = 'saved';
|
||||
upload_complete = true;
|
||||
// Cleanup after batch
|
||||
$events_sess.files.processed_file_list = [];
|
||||
target.reset();
|
||||
|
||||
// Refresh Local Cache (Optimistic Revalidation)
|
||||
await db_events.file.clear();
|
||||
events_func.load_ae_obj_li__event_file({
|
||||
api_cfg: $ae_api,
|
||||
for_obj_type: link_to_type,
|
||||
for_obj_id: link_to_id,
|
||||
enabled: 'all',
|
||||
hidden: 'all',
|
||||
try_cache: true
|
||||
});
|
||||
}
|
||||
|
||||
async function handle_input_upload_files({
|
||||
input_upload_files,
|
||||
task_id
|
||||
}: {
|
||||
input_upload_files: any[];
|
||||
task_id: string;
|
||||
}) {
|
||||
if (log_lvl)
|
||||
console.log(
|
||||
`*** handle_input_upload_files() *** task_id = ${task_id}`
|
||||
);
|
||||
$events_sess.files.disable_submit__event_file_obj = false;
|
||||
$events_sess.files.submit_status = 'saved';
|
||||
submit_status = 'saved';
|
||||
upload_complete = true;
|
||||
}
|
||||
|
||||
const form_data = new FormData();
|
||||
form_data.append('account_id', $ae_loc.account_id);
|
||||
form_data.append('link_to_type', link_to_type);
|
||||
form_data.append('link_to_id', link_to_id);
|
||||
async function handle_input_upload_files({
|
||||
input_upload_files,
|
||||
task_id
|
||||
}: {
|
||||
input_upload_files: any[];
|
||||
task_id: string;
|
||||
}) {
|
||||
if (log_lvl)
|
||||
console.log(`*** handle_input_upload_files() *** task_id = ${task_id}`);
|
||||
|
||||
for (let i = 0; i < input_upload_files.length; i++) {
|
||||
form_data.append(`file_list`, input_upload_files[i]);
|
||||
}
|
||||
const form_data = new FormData();
|
||||
form_data.append('account_id', $ae_loc.account_id);
|
||||
form_data.append('link_to_type', link_to_type);
|
||||
form_data.append('link_to_id', link_to_id);
|
||||
|
||||
// STEP 1: Upload to Hosted Files
|
||||
ae_promises.upload__hosted_file_obj = api
|
||||
.post_object({
|
||||
api_cfg: $ae_api,
|
||||
endpoint: '/hosted_file/upload_files',
|
||||
form_data: form_data,
|
||||
task_id: task_id,
|
||||
log_lvl: log_lvl
|
||||
})
|
||||
.then(async function (result) {
|
||||
// WARNING: endpoint returns a list, we sequentially handle one at a time.
|
||||
const hosted_file_obj = result[0];
|
||||
const hosted_file_id = hosted_file_obj.hosted_file_id;
|
||||
for (let i = 0; i < input_upload_files.length; i++) {
|
||||
form_data.append(`file_list`, input_upload_files[i]);
|
||||
}
|
||||
|
||||
const event_file_data: key_val = {
|
||||
// STEP 1: Upload to Hosted Files
|
||||
ae_promises.upload__hosted_file_obj = api
|
||||
.post_object({
|
||||
api_cfg: $ae_api,
|
||||
endpoint: '/hosted_file/upload_files',
|
||||
form_data: form_data,
|
||||
task_id: task_id,
|
||||
log_lvl: log_lvl
|
||||
})
|
||||
.then(async function (result) {
|
||||
// WARNING: endpoint returns a list, we sequentially handle one at a time.
|
||||
const hosted_file_obj = result[0];
|
||||
const hosted_file_id = hosted_file_obj.hosted_file_id;
|
||||
|
||||
const event_file_data: key_val = {
|
||||
hosted_file_id: hosted_file_id,
|
||||
for_type: link_to_type,
|
||||
for_id: link_to_id,
|
||||
filename: hosted_file_obj.filename,
|
||||
extension: hosted_file_obj.extension,
|
||||
enable: true
|
||||
};
|
||||
|
||||
// STEP 2: Create Event File Link
|
||||
return await events_func.create_event_file_obj_from_hosted_file_async(
|
||||
{
|
||||
api_cfg: $ae_api,
|
||||
hosted_file_id: hosted_file_id,
|
||||
for_type: link_to_type,
|
||||
for_id: link_to_id,
|
||||
filename: hosted_file_obj.filename,
|
||||
extension: hosted_file_obj.extension,
|
||||
enable: true
|
||||
};
|
||||
data: event_file_data,
|
||||
log_lvl: log_lvl
|
||||
}
|
||||
);
|
||||
})
|
||||
.catch(function (error: any) {
|
||||
console.error('Upload Process Failed:', error);
|
||||
return false;
|
||||
})
|
||||
.finally(function () {
|
||||
$slct_trigger = 'load__event_file_obj_li';
|
||||
});
|
||||
|
||||
// STEP 2: Create Event File Link
|
||||
return await events_func.create_event_file_obj_from_hosted_file_async(
|
||||
{
|
||||
api_cfg: $ae_api,
|
||||
hosted_file_id: hosted_file_id,
|
||||
data: event_file_data,
|
||||
log_lvl: log_lvl
|
||||
}
|
||||
);
|
||||
})
|
||||
.catch(function (error: any) {
|
||||
console.error('Upload Process Failed:', error);
|
||||
return false;
|
||||
})
|
||||
.finally(function () {
|
||||
$slct_trigger = 'load__event_file_obj_li';
|
||||
});
|
||||
|
||||
return ae_promises.upload__hosted_file_obj;
|
||||
}
|
||||
return ae_promises.upload__hosted_file_obj;
|
||||
}
|
||||
</script>
|
||||
|
||||
<form
|
||||
onsubmit={prevent_default(handle_submit_form_files)}
|
||||
class="{class_li_default} {class_li}"
|
||||
>
|
||||
class="{class_li_default} {class_li}">
|
||||
{#await ae_promises.upload__hosted_file_obj}
|
||||
<div class="text-lg flex flex-row gap-1 items-center justify-center">
|
||||
<LoaderCircle class="animate-spin m-1" />
|
||||
<div class="flex flex-row items-center justify-center gap-1 text-lg">
|
||||
<LoaderCircle class="m-1 animate-spin" />
|
||||
<span class="">
|
||||
Uploading
|
||||
{#if $ae_sess.api_upload_kv[task_id]}
|
||||
@@ -212,31 +209,27 @@
|
||||
|
||||
<div
|
||||
class="
|
||||
border-2 hover:border-2 border-dashed border-primary-500
|
||||
p-1 w-full rounded-lg
|
||||
preset-filled-primary-50-950 hover:border-primary-800
|
||||
cursor-pointer transition-colors
|
||||
"
|
||||
>
|
||||
border-primary-500 preset-filled-primary-50-950 hover:border-primary-800 w-full
|
||||
cursor-pointer rounded-lg border-2
|
||||
border-dashed p-1
|
||||
transition-colors hover:border-2
|
||||
">
|
||||
<label
|
||||
for={input_element_id}
|
||||
class="
|
||||
svelte_input_file_label
|
||||
text-center
|
||||
cursor-pointer
|
||||
text-center
|
||||
"
|
||||
class:hidden={$events_sess.files.disable_submit__event_file_obj}
|
||||
>
|
||||
class:hidden={$events_sess.files.disable_submit__event_file_obj}>
|
||||
{#if label}{@render label()}{:else}
|
||||
<div class="flex items-center justify-center gap-2 mb-2 pt-2">
|
||||
<div class="mb-2 flex items-center justify-center gap-2 pt-2">
|
||||
<Upload class="text-primary-500" />
|
||||
<strong class="preset-tonal-primary px-3 py-1 rounded-full"
|
||||
>Select Files</strong
|
||||
>
|
||||
<strong class="preset-tonal-primary rounded-full px-3 py-1"
|
||||
>Select Files</strong>
|
||||
</div>
|
||||
<div
|
||||
class="text-sm text-gray-600 dark:text-gray-400 italic pb-2"
|
||||
>
|
||||
class="pb-2 text-sm text-gray-600 italic dark:text-gray-400">
|
||||
<strong>Presentation materials only</strong><br />
|
||||
(PPTX, Keynote, PDF, MP4, etc)
|
||||
</div>
|
||||
@@ -254,39 +247,36 @@
|
||||
class:hidden={$events_sess.files.disable_submit__event_file_obj}
|
||||
class="
|
||||
svelte_input_file_element file-dropzone-input
|
||||
block w-full text-lg text-center
|
||||
rounded-lg
|
||||
preset-tonal-primary preset-outlined-primary-200-800 hover:preset-filled-success-200-800 block
|
||||
w-full
|
||||
cursor-pointer
|
||||
p-1
|
||||
preset-tonal-primary preset-outlined-primary-200-800 hover:preset-filled-success-200-800
|
||||
rounded-lg
|
||||
p-1 text-center text-lg
|
||||
transition-all
|
||||
{input_class_li.join(' ')}
|
||||
"
|
||||
/>
|
||||
" />
|
||||
</div>
|
||||
|
||||
<Element_input_files_tbl
|
||||
bind:input_file_list
|
||||
bind:file_list_status={$events_sess.files.status__file_list}
|
||||
bind:processed_file_list={$events_sess.files.processed_file_list}
|
||||
{table_class_li}
|
||||
/>
|
||||
{table_class_li} />
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
class="
|
||||
btn btn-lg
|
||||
preset-tonal-primary
|
||||
border-primary-500 hover:preset-tonal-success hover:border-success-500 flex w-54
|
||||
items-center justify-center border
|
||||
text-lg
|
||||
preset-tonal-primary border border-primary-500 hover:preset-tonal-success hover:border-success-500
|
||||
flex items-center justify-center
|
||||
w-54
|
||||
transition-all
|
||||
"
|
||||
disabled={$events_sess.files.disable_submit__event_file_obj ||
|
||||
$events_sess.files.status__file_list != 'ready'}
|
||||
>
|
||||
$events_sess.files.status__file_list != 'ready'}>
|
||||
{#await ae_promises.upload__hosted_file_obj}
|
||||
<LoaderCircle class="animate-spin m-1" />
|
||||
<LoaderCircle class="m-1 animate-spin" />
|
||||
<span class="">
|
||||
{#if $ae_sess.api_upload_kv[task_id]}
|
||||
{$ae_sess.api_upload_kv[task_id].percent_completed}%
|
||||
@@ -297,7 +287,7 @@
|
||||
{:then}
|
||||
<UploadCloud class="m-1" size={20} />
|
||||
<span class="text-sm"> Upload </span>
|
||||
<span class="grow font-bold ml-2">
|
||||
<span class="ml-2 grow font-bold">
|
||||
{#if $events_sess.files.processed_file_list?.length > 0}
|
||||
{$events_sess.files.processed_file_list.length}
|
||||
{$events_sess.files.processed_file_list.length === 1
|
||||
|
||||
@@ -1,55 +1,61 @@
|
||||
<script lang="ts">
|
||||
interface Props {
|
||||
// Exports
|
||||
container_class_li?: string | Array<string>;
|
||||
display_mode?: string; // 'default', 'compact', 'minimal', 'launcher'
|
||||
// export let link_to_id: string;
|
||||
lq__event_presentation_obj_li: any;
|
||||
log_lvl?: number; // Variables
|
||||
}
|
||||
interface Props {
|
||||
// Exports
|
||||
container_class_li?: string | Array<string>;
|
||||
display_mode?: string; // 'default', 'compact', 'minimal', 'launcher'
|
||||
// export let link_to_id: string;
|
||||
lq__event_presentation_obj_li: any;
|
||||
log_lvl?: number; // Variables
|
||||
}
|
||||
|
||||
let {
|
||||
container_class_li = [],
|
||||
display_mode = 'default',
|
||||
lq__event_presentation_obj_li,
|
||||
log_lvl = 0
|
||||
}: Props = $props();
|
||||
let {
|
||||
container_class_li = [],
|
||||
display_mode = 'default',
|
||||
lq__event_presentation_obj_li,
|
||||
log_lvl = 0
|
||||
}: Props = $props();
|
||||
|
||||
// Imports
|
||||
import { ae_util } from '$lib/ae_utils/ae_utils';
|
||||
import {
|
||||
ae_snip,
|
||||
ae_loc,
|
||||
ae_sess,
|
||||
ae_api,
|
||||
ae_trig,
|
||||
slct,
|
||||
slct_trigger
|
||||
} from '$lib/stores/ae_stores';
|
||||
import { events_func } from '$lib/ae_events/ae_events_functions';
|
||||
import {
|
||||
events_loc,
|
||||
events_sess,
|
||||
events_slct,
|
||||
events_trigger,
|
||||
events_trig_kv
|
||||
} from '$lib/stores/ae_events_stores';
|
||||
import Element_ae_obj_field_editor from '$lib/elements/element_ae_obj_field_editor.svelte';
|
||||
import Comp_event_presenter_obj_li from '../events/[event_id]/(pres_mgmt)/presenter/ae_comp__event_presenter_obj_li_wrapper.svelte';
|
||||
import Element_manage_event_file_li_wrap from '$lib/elements/element_manage_event_file_li_all.svelte';
|
||||
import { Barcode, CalendarDays, Eye, EyeOff, ListOrdered, Plus } from '@lucide/svelte';
|
||||
// export let link_to_type: string;
|
||||
// Imports
|
||||
import { ae_util } from '$lib/ae_utils/ae_utils';
|
||||
import {
|
||||
ae_snip,
|
||||
ae_loc,
|
||||
ae_sess,
|
||||
ae_api,
|
||||
ae_trig,
|
||||
slct,
|
||||
slct_trigger
|
||||
} from '$lib/stores/ae_stores';
|
||||
import { events_func } from '$lib/ae_events/ae_events_functions';
|
||||
import {
|
||||
events_loc,
|
||||
events_sess,
|
||||
events_slct,
|
||||
events_trigger,
|
||||
events_trig_kv
|
||||
} from '$lib/stores/ae_events_stores';
|
||||
import Element_ae_obj_field_editor from '$lib/elements/element_ae_obj_field_editor.svelte';
|
||||
import Comp_event_presenter_obj_li from '../events/[event_id]/(pres_mgmt)/presenter/ae_comp__event_presenter_obj_li_wrapper.svelte';
|
||||
import Element_manage_event_file_li_wrap from '$lib/elements/element_manage_event_file_li_all.svelte';
|
||||
import {
|
||||
Barcode,
|
||||
CalendarDays,
|
||||
Eye,
|
||||
EyeOff,
|
||||
ListOrdered,
|
||||
Plus
|
||||
} from '@lucide/svelte';
|
||||
// export let link_to_type: string;
|
||||
|
||||
// let ae_promises: key_val = {};
|
||||
// let ae_tmp: key_val = {};
|
||||
// let ae_triggers: key_val = {};
|
||||
// let ae_promises: key_val = {};
|
||||
// let ae_tmp: key_val = {};
|
||||
// let ae_triggers: key_val = {};
|
||||
|
||||
// *** Functions and Logic
|
||||
// *** Functions and Logic
|
||||
</script>
|
||||
|
||||
<section
|
||||
class="ae_comp event_presentation_obj_li px-0.5 py-2 space-y-2 min-w-full w-full container overflow-x-auto {container_class_li}"
|
||||
>
|
||||
class="ae_comp event_presentation_obj_li container w-full min-w-full space-y-2 overflow-x-auto px-0.5 py-2 {container_class_li}">
|
||||
<div class="float-right flex flex-row items-center">
|
||||
{#if $ae_loc.trusted_access && $ae_loc.edit_mode}
|
||||
<button
|
||||
@@ -77,8 +83,7 @@
|
||||
log_lvl: 1
|
||||
});
|
||||
}}
|
||||
class="btn btn-sm preset-tonal-warning hover:preset-filled-warning-500"
|
||||
>
|
||||
class="btn btn-sm preset-tonal-warning hover:preset-filled-warning-500">
|
||||
<Plus size="1em" class="mx-1" />
|
||||
Add Presentation
|
||||
</button>
|
||||
@@ -93,10 +98,9 @@
|
||||
|
||||
{#if lq__event_presentation_obj_li?.length}
|
||||
<span
|
||||
class="text-3xl font-bold preset-filled-success-100-900 px-4 rounded-lg"
|
||||
class="preset-filled-success-100-900 rounded-lg px-4 text-3xl font-bold"
|
||||
title="Count {lq__event_presentation_obj_li.length ??
|
||||
'None'}"
|
||||
>
|
||||
'None'}">
|
||||
<ListOrdered size="1em" class="mx-4" />
|
||||
{lq__event_presentation_obj_li.length ?? 'None'}×
|
||||
</span>
|
||||
@@ -114,8 +118,9 @@
|
||||
<!-- Show presentations for this LiveQuery -->
|
||||
<ul class="space-y-4">
|
||||
{#each lq__event_presentation_obj_li ?? [] as event_presentation_obj (event_presentation_obj.event_presentation_id)}
|
||||
<li class="space-y-3 border border-surface-200-800 bg-surface-50-900 p-4 rounded-xl shadow-sm transition-colors duration-200">
|
||||
<div class="float-right space-2 flex flex-row items-center">
|
||||
<li
|
||||
class="border-surface-200-800 bg-surface-50-900 space-y-3 rounded-xl border p-4 shadow-sm transition-colors duration-200">
|
||||
<div class="space-2 float-right flex flex-row items-center">
|
||||
{#if $ae_loc.trusted_access && $ae_loc.edit_mode}
|
||||
<button
|
||||
type="button"
|
||||
@@ -147,21 +152,19 @@
|
||||
log_lvl: 1
|
||||
});
|
||||
}}
|
||||
class="btn btn-sm preset-tonal-warning hover:preset-filled-warning-500"
|
||||
>
|
||||
class="btn btn-sm preset-tonal-warning hover:preset-filled-warning-500">
|
||||
<Plus size="1em" class="mx-1" />
|
||||
Add Presenter
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<h4 class="text-lg font-bold rounded-lg px-3 py-2 bg-surface-100-900 flex flex-wrap items-center gap-2">
|
||||
<h4
|
||||
class="bg-surface-100-900 flex flex-wrap items-center gap-2 rounded-lg px-3 py-2 text-lg font-bold">
|
||||
<span
|
||||
class:hidden={!event_presentation_obj.start_datetime ||
|
||||
$events_loc.pres_mgmt
|
||||
.hide__presentation_datetime}
|
||||
class="text-base border-r-2 border-gray-800/50 px-1"
|
||||
>
|
||||
$events_loc.pres_mgmt.hide__presentation_datetime}
|
||||
class="border-r-2 border-gray-800/50 px-1 text-base">
|
||||
{ae_util.iso_datetime_formatter(
|
||||
event_presentation_obj.start_datetime,
|
||||
'dddd'
|
||||
@@ -182,8 +185,13 @@
|
||||
field_type={'text'}
|
||||
current_value={event_presentation_obj?.name}
|
||||
display_block={true}
|
||||
on_success={() => events_func.load_ae_obj_id__event_presentation({ api_cfg: $ae_api, event_presentation_id: event_presentation_obj.event_presentation_id, log_lvl: 1 })}
|
||||
>
|
||||
on_success={() =>
|
||||
events_func.load_ae_obj_id__event_presentation({
|
||||
api_cfg: $ae_api,
|
||||
event_presentation_id:
|
||||
event_presentation_obj.event_presentation_id,
|
||||
log_lvl: 1
|
||||
})}>
|
||||
<span class="italic">
|
||||
{event_presentation_obj?.name}
|
||||
</span>
|
||||
@@ -197,28 +205,29 @@
|
||||
field_type={'text'}
|
||||
current_value={event_presentation_obj?.code}
|
||||
display_block={true}
|
||||
on_success={() => events_func.load_ae_obj_id__event_presentation({ api_cfg: $ae_api, event_presentation_id: event_presentation_obj.event_presentation_id, log_lvl: 1 })}
|
||||
>
|
||||
on_success={() =>
|
||||
events_func.load_ae_obj_id__event_presentation({
|
||||
api_cfg: $ae_api,
|
||||
event_presentation_id:
|
||||
event_presentation_obj.event_presentation_id,
|
||||
log_lvl: 1
|
||||
})}>
|
||||
{#if (event_presentation_obj?.code || event_presentation_obj?.abstract_code) && !$events_loc.pres_mgmt.hide__presentation_code}
|
||||
<span
|
||||
class="text-xs preset-tonal-warning px-2 py-0.5 rounded-md leading-none"
|
||||
title="Presentation code {event_presentation_obj?.code} and abstract code {event_presentation_obj?.abstract_code}"
|
||||
>
|
||||
class="preset-tonal-warning rounded-md px-2 py-0.5 text-xs leading-none"
|
||||
title="Presentation code {event_presentation_obj?.code} and abstract code {event_presentation_obj?.abstract_code}">
|
||||
<Barcode size="1em" />
|
||||
{event_presentation_obj?.code ?? ''}
|
||||
{event_presentation_obj?.abstract_code ??
|
||||
''}
|
||||
{event_presentation_obj?.abstract_code ?? ''}
|
||||
</span>
|
||||
{:else if $ae_loc.trusted_access && $ae_loc.edit_mode}
|
||||
<span
|
||||
class="text-sm text-semibold text-success-800-400"
|
||||
>
|
||||
class="text-semibold text-success-800-400 text-sm">
|
||||
<Barcode size="1em" />
|
||||
Code:
|
||||
<span
|
||||
class=""
|
||||
title="No code provided for this presentation"
|
||||
>
|
||||
title="No code provided for this presentation">
|
||||
{@html event_presentation_obj?.code ??
|
||||
ae_snip.html__not_set}
|
||||
</span>
|
||||
@@ -231,18 +240,13 @@
|
||||
<div
|
||||
class:hidden={!(
|
||||
$ae_loc.trusted_access && $ae_loc.edit_mode
|
||||
)}
|
||||
>
|
||||
<span
|
||||
class="text-sm text-semibold text-success-800-400"
|
||||
>
|
||||
)}>
|
||||
<span class="text-semibold text-success-800-400 text-sm">
|
||||
Date &
|
||||
<button
|
||||
type="button"
|
||||
onclick={() => {
|
||||
if (
|
||||
$events_loc.pres_mgmt.time_hours == 12
|
||||
) {
|
||||
if ($events_loc.pres_mgmt.time_hours == 12) {
|
||||
$events_loc.pres_mgmt.time_hours = 24;
|
||||
$events_loc.pres_mgmt.datetime_format =
|
||||
'datetime_long';
|
||||
@@ -255,12 +259,10 @@
|
||||
$events_loc.pres_mgmt.time_format =
|
||||
'time_12_short';
|
||||
}
|
||||
}}
|
||||
>
|
||||
}}>
|
||||
time
|
||||
</button>
|
||||
:</span
|
||||
>
|
||||
:</span>
|
||||
<CalendarDays size="1em" class="text-success-800-400" />
|
||||
<Element_ae_obj_field_editor
|
||||
object_type={'event_presentation'}
|
||||
@@ -268,8 +270,12 @@
|
||||
field_name={'start_datetime'}
|
||||
field_type={'datetime'}
|
||||
current_value={event_presentation_obj.start_datetime}
|
||||
on_success={() => events_func.load_ae_obj_id__event_presentation({ api_cfg: $ae_api, event_presentation_id: event_presentation_obj?.event_presentation_id })}
|
||||
>
|
||||
on_success={() =>
|
||||
events_func.load_ae_obj_id__event_presentation({
|
||||
api_cfg: $ae_api,
|
||||
event_presentation_id:
|
||||
event_presentation_obj?.event_presentation_id
|
||||
})}>
|
||||
{ae_util.iso_datetime_formatter(
|
||||
event_presentation_obj.start_datetime,
|
||||
'dddd'
|
||||
@@ -286,8 +292,12 @@
|
||||
field_name={'end_datetime'}
|
||||
field_type={'datetime'}
|
||||
current_value={event_presentation_obj.end_datetime}
|
||||
on_success={() => events_func.load_ae_obj_id__event_presentation({ api_cfg: $ae_api, event_presentation_id: event_presentation_obj?.event_presentation_id })}
|
||||
>
|
||||
on_success={() =>
|
||||
events_func.load_ae_obj_id__event_presentation({
|
||||
api_cfg: $ae_api,
|
||||
event_presentation_id:
|
||||
event_presentation_obj?.event_presentation_id
|
||||
})}>
|
||||
{ae_util.iso_datetime_formatter(
|
||||
event_presentation_obj.end_datetime,
|
||||
$events_loc.pres_mgmt.time_format
|
||||
@@ -298,8 +308,7 @@
|
||||
<div
|
||||
class:hidden={!$events_loc.pres_mgmt
|
||||
.show_content__presentation_description &&
|
||||
!($ae_loc.trusted_access && $ae_loc.edit_mode)}
|
||||
>
|
||||
!($ae_loc.trusted_access && $ae_loc.edit_mode)}>
|
||||
<Element_ae_obj_field_editor
|
||||
object_type={'event_presentation'}
|
||||
object_id={event_presentation_obj?.event_presentation_id}
|
||||
@@ -309,11 +318,15 @@
|
||||
allow_null={true}
|
||||
display_block={true}
|
||||
textarea_rows={15}
|
||||
on_success={() => events_func.load_ae_obj_id__event_presentation({ api_cfg: $ae_api, event_presentation_id: event_presentation_obj.event_presentation_id, log_lvl: 1 })}
|
||||
>
|
||||
on_success={() =>
|
||||
events_func.load_ae_obj_id__event_presentation({
|
||||
api_cfg: $ae_api,
|
||||
event_presentation_id:
|
||||
event_presentation_obj.event_presentation_id,
|
||||
log_lvl: 1
|
||||
})}>
|
||||
<span
|
||||
class="text-sm text-semibold text-success-800-400"
|
||||
>
|
||||
class="text-semibold text-success-800-400 text-sm">
|
||||
Description:
|
||||
</span>
|
||||
|
||||
@@ -342,8 +355,7 @@
|
||||
event_presentation_obj.event_presentation_id;
|
||||
}
|
||||
}}
|
||||
class="btn btn-sm preset-tonal-surface hover:preset-filled-surface-500 text-xs"
|
||||
>
|
||||
class="btn btn-sm preset-tonal-surface hover:preset-filled-surface-500 text-xs">
|
||||
{#if $events_sess.pres_mgmt.show_content__presentation_description == event_presentation_obj.event_presentation_id}
|
||||
<EyeOff size="1em" class="mx-1" />
|
||||
<span>Hide Description</span>
|
||||
@@ -354,7 +366,7 @@
|
||||
</button>
|
||||
|
||||
<pre
|
||||
class="whitespace-pre-wrap p-3 bg-surface-100-900 rounded-lg text-sm"
|
||||
class="bg-surface-100-900 rounded-lg p-3 text-sm whitespace-pre-wrap"
|
||||
class:hidden={$events_sess.pres_mgmt
|
||||
.show_content__presentation_description !==
|
||||
event_presentation_obj.event_presentation_id}>{event_presentation_obj.description}</pre>
|
||||
@@ -377,8 +389,7 @@
|
||||
link_to_type={'event_presentation'}
|
||||
link_to_id={event_presentation_obj.event_presentation_id}
|
||||
event_presenter_id_li={[]}
|
||||
log_lvl={2}
|
||||
></Comp_event_presenter_obj_li>
|
||||
log_lvl={2}></Comp_event_presenter_obj_li>
|
||||
|
||||
<!-- Show files for this presentation -->
|
||||
<Element_manage_event_file_li_wrap
|
||||
@@ -393,8 +404,7 @@
|
||||
allow_moderator={$events_loc.auth__kv.session[
|
||||
$events_slct.event_session_id
|
||||
]}
|
||||
container_class_li={''}
|
||||
/>
|
||||
container_class_li={''} />
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
|
||||
@@ -1,104 +1,120 @@
|
||||
<script lang="ts">
|
||||
interface Props {
|
||||
log_lvl?: number;
|
||||
container_class_li?: string | Array<string>;
|
||||
lq__event_session_obj_li?: any;
|
||||
event_session_obj_li?: any[] | null;
|
||||
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;
|
||||
}
|
||||
interface Props {
|
||||
log_lvl?: number;
|
||||
container_class_li?: string | Array<string>;
|
||||
lq__event_session_obj_li?: any;
|
||||
event_session_obj_li?: any[] | null;
|
||||
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 = null,
|
||||
event_session_obj_li = null,
|
||||
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();
|
||||
let {
|
||||
log_lvl = 0,
|
||||
container_class_li = [],
|
||||
lq__event_session_obj_li = null,
|
||||
event_session_obj_li = null,
|
||||
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 { Bell, BellOff, CalendarDays, Check, ChevronDown, ChevronUp, Clock, Edit, Eye, EyeOff, FileSearch, LoaderCircle, Mail, MapPin, Presentation, Rocket, Search, SendHorizontal, User } from '@lucide/svelte';
|
||||
import { api } from '$lib/api/api';
|
||||
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 { ae_util } from '$lib/ae_utils/ae_utils';
|
||||
import {
|
||||
Bell,
|
||||
BellOff,
|
||||
CalendarDays,
|
||||
Check,
|
||||
ChevronDown,
|
||||
ChevronUp,
|
||||
Clock,
|
||||
Edit,
|
||||
Eye,
|
||||
EyeOff,
|
||||
FileSearch,
|
||||
LoaderCircle,
|
||||
Mail,
|
||||
MapPin,
|
||||
Presentation,
|
||||
Rocket,
|
||||
Search,
|
||||
SendHorizontal,
|
||||
User
|
||||
} from '@lucide/svelte';
|
||||
import { api } from '$lib/api/api';
|
||||
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 { events_func } from '$lib/ae_events/ae_events_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';
|
||||
import { events_func } from '$lib/ae_events/ae_events_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({});
|
||||
let show_details_kv: Record<string, boolean> = $state({});
|
||||
|
||||
// Derived list of visible items (Standardized Pattern 2026-01-27)
|
||||
// Supports both a liveQuery observable (lq__event_session_obj_li) and a
|
||||
// plain pre-fetched array (event_session_obj_li) as a fallback.
|
||||
let visible_session_obj_li = $derived(
|
||||
(() => {
|
||||
const list = $lq__event_session_obj_li ?? event_session_obj_li;
|
||||
if (list === undefined || list === null) return null;
|
||||
if (!Array.isArray(list)) return [];
|
||||
// Derived list of visible items (Standardized Pattern 2026-01-27)
|
||||
// Supports both a liveQuery observable (lq__event_session_obj_li) and a
|
||||
// plain pre-fetched array (event_session_obj_li) as a fallback.
|
||||
let visible_session_obj_li = $derived(
|
||||
(() => {
|
||||
const list = $lq__event_session_obj_li ?? 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;
|
||||
});
|
||||
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;
|
||||
})()
|
||||
);
|
||||
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];
|
||||
}
|
||||
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}"
|
||||
>
|
||||
class="ae_comp event_session_obj_li container w-full min-w-full space-y-2 overflow-x-auto px-0.5 py-2 {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" />
|
||||
<LoaderCircle size="3em" class="mb-2 animate-spin" />
|
||||
|
||||
<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>
|
||||
class="mb-2 flex w-full flex-row items-center justify-start gap-2 px-2">
|
||||
<h2 class="text-sm font-normal text-gray-500">Sessions:</h2>
|
||||
|
||||
<span
|
||||
class="badge preset-tonal-success font-bold text-lg px-3 py-1"
|
||||
>
|
||||
class="badge preset-tonal-success px-3 py-1 text-lg font-bold">
|
||||
{visible_session_obj_li.length}<span
|
||||
class="text-gray-400 dark:text-gray-600">×</span
|
||||
>
|
||||
class="text-gray-400 dark:text-gray-600">×</span>
|
||||
</span>
|
||||
</header>
|
||||
|
||||
<table class="table table-auto table-striped w-full">
|
||||
<table class="table-striped table w-full table-auto">
|
||||
<thead>
|
||||
<tr class="bg-surface-100-900">
|
||||
<th>Session</th>
|
||||
@@ -112,8 +128,7 @@
|
||||
<th
|
||||
class:hidden={!$ae_loc.edit_mode ||
|
||||
!$ae_loc.adv_mode ||
|
||||
hide__admin}>Admin</th
|
||||
>
|
||||
hide__admin}>Admin</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
@@ -122,40 +137,34 @@
|
||||
<tr
|
||||
class="relative transition-colors duration-200"
|
||||
class:opacity-50={session_obj?.hide}
|
||||
class:preset-tonal-warning={!session_obj?.enable}
|
||||
>
|
||||
class:preset-tonal-warning={!session_obj?.enable}>
|
||||
<td>
|
||||
{#if session_obj?.alert && $ae_loc.trusted_access}
|
||||
<Comp_event_session_alert
|
||||
event_session_obj={session_obj}
|
||||
{log_lvl}
|
||||
/>
|
||||
{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 transition-colors duration-200"
|
||||
>
|
||||
class="hover:text-primary-500 flex flex-row items-center gap-2 text-left text-lg font-bold transition-colors duration-200">
|
||||
{#if session_obj?.hide}
|
||||
<EyeOff
|
||||
size="1em"
|
||||
class="text-gray-400 flex-none"
|
||||
/>
|
||||
class="flex-none text-gray-400" />
|
||||
{:else}
|
||||
<Presentation
|
||||
size="1em"
|
||||
class="text-primary-500 flex-none"
|
||||
/>
|
||||
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"
|
||||
>
|
||||
class="badge preset-tonal-success flex items-center gap-1 px-1 py-0 text-xs">
|
||||
<Check size="1em" />
|
||||
|
||||
{session_obj.file_count_all}
|
||||
@@ -170,8 +179,7 @@
|
||||
onclick={() =>
|
||||
toggle_details(
|
||||
session_obj.event_session_id
|
||||
)}
|
||||
>
|
||||
)}>
|
||||
{#if show_details_kv[session_obj.event_session_id]}
|
||||
<ChevronUp size="1.2em" />
|
||||
{:else}
|
||||
@@ -184,36 +192,31 @@
|
||||
<!-- Mobile Schedule Summary -->
|
||||
|
||||
<div
|
||||
class="md:hidden text-xs text-surface-500 flex flex-wrap gap-x-3 gap-y-1"
|
||||
>
|
||||
class="text-surface-500 flex flex-wrap gap-x-3 gap-y-1 text-xs md:hidden">
|
||||
<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>
|
||||
|
||||
<span class="flex items-center gap-1"
|
||||
><Clock size="1em" />
|
||||
{ae_util.iso_datetime_formatter(
|
||||
session_obj?.start_datetime,
|
||||
'time_12_short'
|
||||
)}</span
|
||||
>
|
||||
)}</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"
|
||||
>
|
||||
class="bg-surface-500/5 border-surface-500/10 mt-1 rounded-lg border p-2">
|
||||
{#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}
|
||||
/>
|
||||
{log_lvl} />
|
||||
{/if}
|
||||
|
||||
{#if show__session_files && $ae_loc.manager_access}
|
||||
@@ -222,8 +225,7 @@
|
||||
link_to_id={session_obj?.event_session_id}
|
||||
allow_basic={true}
|
||||
allow_moderator={true}
|
||||
display_mode={'minimal'}
|
||||
/>
|
||||
display_mode={'minimal'} />
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
@@ -236,8 +238,7 @@
|
||||
>{ae_util.iso_datetime_formatter(
|
||||
session_obj?.start_datetime,
|
||||
'dddd, MMM D'
|
||||
)}</span
|
||||
>
|
||||
)}</span>
|
||||
|
||||
<span class="text-surface-500 whitespace-nowrap"
|
||||
>{ae_util.iso_datetime_formatter(
|
||||
@@ -246,17 +247,15 @@
|
||||
)} – {ae_util.iso_datetime_formatter(
|
||||
session_obj?.end_datetime,
|
||||
'time_12_short'
|
||||
)}</span
|
||||
>
|
||||
)}</span>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td class:hidden={hide__session_location}>
|
||||
<div class="flex flex-col gap-1 min-w-32">
|
||||
<div class="flex min-w-32 flex-col gap-1">
|
||||
<span class="text-xs font-semibold"
|
||||
>{session_obj?.event_location_name ??
|
||||
'--'}</span
|
||||
>
|
||||
'--'}</span>
|
||||
|
||||
<div class="flex gap-1">
|
||||
{#if !hide__launcher_link}
|
||||
@@ -264,8 +263,7 @@
|
||||
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
|
||||
>
|
||||
><Rocket size="1em" /></a>
|
||||
{/if}
|
||||
|
||||
{#if !hide__location_link}
|
||||
@@ -273,28 +271,25 @@
|
||||
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
|
||||
>
|
||||
><MapPin size="1em" /></a>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td class:hidden={hide__session_poc}>
|
||||
<div class="flex flex-col text-xs min-w-32">
|
||||
<div class="flex min-w-32 flex-col text-xs">
|
||||
{#if session_obj?.poc_person_full_name}
|
||||
<span
|
||||
class="font-bold flex items-center gap-1"
|
||||
class="flex items-center gap-1 font-bold"
|
||||
><User size="1em" />
|
||||
{session_obj.poc_person_full_name}</span
|
||||
>
|
||||
{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
|
||||
>
|
||||
class="text-primary-500 flex items-center gap-1 hover:underline"
|
||||
><Mail size="1em" /> Email</a>
|
||||
{/if}
|
||||
{:else}
|
||||
<span class="opacity-30">--</span>
|
||||
@@ -305,8 +300,7 @@
|
||||
<td
|
||||
class:hidden={!$ae_loc.edit_mode ||
|
||||
!$ae_loc.adv_mode ||
|
||||
hide__admin}
|
||||
>
|
||||
hide__admin}>
|
||||
<div class="flex gap-1">
|
||||
<button
|
||||
type="button"
|
||||
@@ -321,15 +315,17 @@
|
||||
fields: { hide: !session_obj.hide },
|
||||
log_lvl: 1
|
||||
});
|
||||
events_func.load_ae_obj_id__event_session({
|
||||
api_cfg: $ae_api,
|
||||
event_session_id: session_obj.event_session_id
|
||||
});
|
||||
}}
|
||||
>
|
||||
events_func.load_ae_obj_id__event_session(
|
||||
{
|
||||
api_cfg: $ae_api,
|
||||
event_session_id:
|
||||
session_obj.event_session_id
|
||||
}
|
||||
);
|
||||
}}>
|
||||
{#if session_obj?.hide}<EyeOff
|
||||
size="1.2em"
|
||||
/>{:else}<Eye size="1.2em" />{/if}
|
||||
size="1.2em" />{:else}<Eye
|
||||
size="1.2em" />{/if}
|
||||
</button>
|
||||
|
||||
<button
|
||||
@@ -342,18 +338,22 @@
|
||||
api_cfg: $ae_api,
|
||||
obj_type: 'event_session',
|
||||
obj_id: session_obj.event_session_id,
|
||||
fields: { alert: !session_obj.alert },
|
||||
fields: {
|
||||
alert: !session_obj.alert
|
||||
},
|
||||
log_lvl: 1
|
||||
});
|
||||
events_func.load_ae_obj_id__event_session({
|
||||
api_cfg: $ae_api,
|
||||
event_session_id: session_obj.event_session_id
|
||||
});
|
||||
}}
|
||||
>
|
||||
events_func.load_ae_obj_id__event_session(
|
||||
{
|
||||
api_cfg: $ae_api,
|
||||
event_session_id:
|
||||
session_obj.event_session_id
|
||||
}
|
||||
);
|
||||
}}>
|
||||
{#if session_obj?.alert}<Bell
|
||||
size="1.2em"
|
||||
/>{:else}<BellOff size="1.2em" />{/if}
|
||||
size="1.2em" />{:else}<BellOff
|
||||
size="1.2em" />{/if}
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
@@ -363,9 +363,8 @@
|
||||
</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" />
|
||||
class="bg-surface-50 dark:bg-surface-900/50 border-surface-300 flex flex-col items-center justify-center rounded-lg border border-dashed p-20 text-center opacity-50">
|
||||
<FileSearch size="3em" class="mx-auto mb-2 opacity-20" />
|
||||
|
||||
<p class="text-xl">No sessions found matching your criteria.</p>
|
||||
|
||||
|
||||
@@ -1,59 +1,59 @@
|
||||
<script lang="ts">
|
||||
interface Props {
|
||||
container_class_li?: string | Array<string>;
|
||||
lq__event_session_obj_li?: any; // New Shared Observable Pattern
|
||||
event_session_id_random_li?: Array<string>;
|
||||
link_to_type?: string;
|
||||
link_to_id?: string;
|
||||
hide__session_location?: boolean;
|
||||
hide__session_poc?: boolean;
|
||||
hide__admin?: boolean;
|
||||
hide__launcher_link_legacy?: boolean;
|
||||
hide__launcher_link?: boolean;
|
||||
hide__location_link?: boolean;
|
||||
log_lvl?: number;
|
||||
}
|
||||
interface Props {
|
||||
container_class_li?: string | Array<string>;
|
||||
lq__event_session_obj_li?: any; // New Shared Observable Pattern
|
||||
event_session_id_random_li?: Array<string>;
|
||||
link_to_type?: string;
|
||||
link_to_id?: string;
|
||||
hide__session_location?: boolean;
|
||||
hide__session_poc?: boolean;
|
||||
hide__admin?: boolean;
|
||||
hide__launcher_link_legacy?: boolean;
|
||||
hide__launcher_link?: boolean;
|
||||
hide__location_link?: boolean;
|
||||
log_lvl?: number;
|
||||
}
|
||||
|
||||
let {
|
||||
container_class_li = [],
|
||||
lq__event_session_obj_li: lq__shared,
|
||||
event_session_id_random_li = [],
|
||||
link_to_type,
|
||||
link_to_id,
|
||||
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),
|
||||
log_lvl = 0
|
||||
}: Props = $props();
|
||||
let {
|
||||
container_class_li = [],
|
||||
lq__event_session_obj_li: lq__shared,
|
||||
event_session_id_random_li = [],
|
||||
link_to_type,
|
||||
link_to_id,
|
||||
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),
|
||||
log_lvl = 0
|
||||
}: Props = $props();
|
||||
|
||||
// Imports
|
||||
import Comp_event_session_obj_li from './ae_comp__event_session_obj_li.svelte';
|
||||
import { liveQuery } from 'dexie';
|
||||
import { db_events } from '$lib/ae_events/db_events';
|
||||
// Imports
|
||||
import Comp_event_session_obj_li from './ae_comp__event_session_obj_li.svelte';
|
||||
import { liveQuery } from 'dexie';
|
||||
import { db_events } from '$lib/ae_events/db_events';
|
||||
|
||||
// Logic: Use shared observable if provided, otherwise create internal one
|
||||
let lq__event_session_obj_li = $derived.by(() => {
|
||||
if (lq__shared) return lq__shared;
|
||||
// Logic: Use shared observable if provided, otherwise create internal one
|
||||
let lq__event_session_obj_li = $derived.by(() => {
|
||||
if (lq__shared) return lq__shared;
|
||||
|
||||
return liveQuery(async () => {
|
||||
if (link_to_type && link_to_id) {
|
||||
const results = await db_events.session
|
||||
.where(`${link_to_type}_id_random`)
|
||||
.equals(link_to_id)
|
||||
.sortBy('start_datetime');
|
||||
return results;
|
||||
} else if (event_session_id_random_li.length > 0) {
|
||||
const results = await db_events.session.bulkGet(
|
||||
event_session_id_random_li
|
||||
);
|
||||
return results.filter((item) => item !== undefined);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
return liveQuery(async () => {
|
||||
if (link_to_type && link_to_id) {
|
||||
const results = await db_events.session
|
||||
.where(`${link_to_type}_id_random`)
|
||||
.equals(link_to_id)
|
||||
.sortBy('start_datetime');
|
||||
return results;
|
||||
} else if (event_session_id_random_li.length > 0) {
|
||||
const results = await db_events.session.bulkGet(
|
||||
event_session_id_random_li
|
||||
);
|
||||
return results.filter((item) => item !== undefined);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<Comp_event_session_obj_li
|
||||
@@ -65,5 +65,4 @@
|
||||
{hide__launcher_link_legacy}
|
||||
{hide__launcher_link}
|
||||
{hide__location_link}
|
||||
{log_lvl}
|
||||
></Comp_event_session_obj_li>
|
||||
{log_lvl}></Comp_event_session_obj_li>
|
||||
|
||||
@@ -1,84 +1,81 @@
|
||||
<script lang="ts">
|
||||
interface Props {
|
||||
container_class_li?: string | Array<string>;
|
||||
// export let event_session_id_random_li: Array<string>;
|
||||
lq__event_session_obj_li: any;
|
||||
log_lvl?: number;
|
||||
show_location_fields?: boolean;
|
||||
hide_session_code?: boolean;
|
||||
interface Props {
|
||||
container_class_li?: string | Array<string>;
|
||||
// export let event_session_id_random_li: Array<string>;
|
||||
lq__event_session_obj_li: any;
|
||||
log_lvl?: number;
|
||||
show_location_fields?: boolean;
|
||||
hide_session_code?: boolean;
|
||||
}
|
||||
|
||||
let {
|
||||
container_class_li = [],
|
||||
lq__event_session_obj_li,
|
||||
log_lvl = $bindable(0),
|
||||
show_location_fields = true,
|
||||
hide_session_code = false
|
||||
}: Props = $props();
|
||||
|
||||
// Imports
|
||||
// import type { key_val } from '$lib/ae_stores';
|
||||
|
||||
// import { liveQuery } from "dexie";
|
||||
import { ae_util } from '$lib/ae_utils/ae_utils';
|
||||
import { ListOrdered } from '@lucide/svelte';
|
||||
// Imports - events specific
|
||||
// import { events_loc, events_sess, events_slct, events_trigger, events_trig_kv } from '$lib/stores/ae_events_stores';
|
||||
// import { db_events } from "$lib/db_events";
|
||||
|
||||
// export let display_mode: string = 'default'; // 'default', 'compact', 'minimal', 'launcher';
|
||||
// export let link_to_type: string;
|
||||
// export let link_to_id: string;
|
||||
|
||||
// *** Functions and Logic
|
||||
$effect(() => {
|
||||
if (log_lvl) {
|
||||
console.log(
|
||||
`container_class_li: ${container_class_li}; show_location_fields: ${show_location_fields}`
|
||||
);
|
||||
// console.log(`link_to_type: ${link_to_type}; link_to_id: ${link_to_id}`);
|
||||
}
|
||||
});
|
||||
|
||||
let {
|
||||
container_class_li = [],
|
||||
lq__event_session_obj_li,
|
||||
log_lvl = $bindable(0),
|
||||
show_location_fields = true,
|
||||
hide_session_code = false
|
||||
}: Props = $props();
|
||||
let horiz_scroll_warning: boolean = $state(false);
|
||||
let horiz_check_element: HTMLElement | null = $state(null);
|
||||
|
||||
// Imports
|
||||
// import type { key_val } from '$lib/ae_stores';
|
||||
|
||||
// import { liveQuery } from "dexie";
|
||||
import { ae_util } from '$lib/ae_utils/ae_utils';
|
||||
import { ListOrdered } from '@lucide/svelte';
|
||||
// Imports - events specific
|
||||
// import { events_loc, events_sess, events_slct, events_trigger, events_trig_kv } from '$lib/stores/ae_events_stores';
|
||||
// import { db_events } from "$lib/db_events";
|
||||
|
||||
// export let display_mode: string = 'default'; // 'default', 'compact', 'minimal', 'launcher';
|
||||
// export let link_to_type: string;
|
||||
// export let link_to_id: string;
|
||||
|
||||
// *** Functions and Logic
|
||||
$effect(() => {
|
||||
if (log_lvl) {
|
||||
console.log(
|
||||
`container_class_li: ${container_class_li}; show_location_fields: ${show_location_fields}`
|
||||
);
|
||||
// console.log(`link_to_type: ${link_to_type}; link_to_id: ${link_to_id}`);
|
||||
}
|
||||
});
|
||||
|
||||
let horiz_scroll_warning: boolean = $state(false);
|
||||
let horiz_check_element: HTMLElement | null = $state(null);
|
||||
|
||||
// Check if element is scrolling horizontally
|
||||
$effect(() => {
|
||||
if (
|
||||
horiz_check_element &&
|
||||
horiz_check_element.scrollWidth > horiz_check_element.offsetWidth
|
||||
) {
|
||||
horiz_scroll_warning = true;
|
||||
// console.log('Element is too wide for the container. Horizontal scrolling detected.');
|
||||
} else {
|
||||
horiz_scroll_warning = false;
|
||||
// console.log('Element fits within the container. No horizontal scrolling.', horiz_check_element);
|
||||
}
|
||||
});
|
||||
// Check if element is scrolling horizontally
|
||||
$effect(() => {
|
||||
if (
|
||||
horiz_check_element &&
|
||||
horiz_check_element.scrollWidth > horiz_check_element.offsetWidth
|
||||
) {
|
||||
horiz_scroll_warning = true;
|
||||
// console.log('Element is too wide for the container. Horizontal scrolling detected.');
|
||||
} else {
|
||||
horiz_scroll_warning = false;
|
||||
// console.log('Element fits within the container. No horizontal scrolling.', horiz_check_element);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<section
|
||||
class:border-r-2={horiz_scroll_warning}
|
||||
class:border-dashed={horiz_scroll_warning}
|
||||
class:border-warning-900-100={horiz_scroll_warning}
|
||||
class="ae_comp event_session_obj_tbl {container_class_li} container overflow-auto max-w-screen"
|
||||
>
|
||||
class="ae_comp event_session_obj_tbl {container_class_li} container max-w-screen overflow-auto">
|
||||
{#if $lq__event_session_obj_li && $lq__event_session_obj_li?.length}
|
||||
<div
|
||||
bind:this={horiz_check_element}
|
||||
id="tbl_container"
|
||||
class="space-y-2 pb-48"
|
||||
>
|
||||
class="space-y-2 pb-48">
|
||||
<h2 class="h3">
|
||||
<span class="text-base"> Results: </span>
|
||||
|
||||
{#if $lq__event_session_obj_li?.length}
|
||||
<span
|
||||
class="text-3xl font-bold preset-filled-success-100-900 px-4 rounded-lg"
|
||||
class="preset-filled-success-100-900 rounded-lg px-4 text-3xl font-bold"
|
||||
title="Count {$lq__event_session_obj_li.length ??
|
||||
'None'}"
|
||||
>
|
||||
'None'}">
|
||||
<ListOrdered size="1em" class="mx-4" />
|
||||
{$lq__event_session_obj_li.length ?? 'None'}×
|
||||
</span>
|
||||
@@ -86,8 +83,7 @@
|
||||
</h2>
|
||||
|
||||
<table
|
||||
class="table table-auto table-striped w-full text-xs lg:text-sm"
|
||||
>
|
||||
class="table-striped table w-full table-auto text-xs lg:text-sm">
|
||||
<thead class="">
|
||||
<tr>
|
||||
<th class="px-4 py-2">Name</th>
|
||||
@@ -105,8 +101,7 @@
|
||||
<td class="px-4 py-2">
|
||||
<a
|
||||
href="/events/{event_session_obj?.event_id}/session/{event_session_obj?.event_session_id}"
|
||||
class="text-blue-500 hover:text-blue-800 hover:underline"
|
||||
>
|
||||
class="text-blue-500 hover:text-blue-800 hover:underline">
|
||||
{event_session_obj?.name}
|
||||
</a>
|
||||
</td>
|
||||
|
||||
@@ -1,135 +1,135 @@
|
||||
<script lang="ts">
|
||||
interface Props {
|
||||
// Exports
|
||||
container_class_li?: string | Array<string>;
|
||||
// export let display_mode: string = 'default'; // 'default', 'compact', 'minimal', 'launcher'
|
||||
// event_session_id_random_li: Array<string>;
|
||||
event_session_obj_li?: Array<any>;
|
||||
link_to_type: string;
|
||||
link_to_id: string;
|
||||
// export let lq__event_presentation_obj
|
||||
log_lvl?: number;
|
||||
show_location_fields?: boolean;
|
||||
hide_session_code?: boolean;
|
||||
interface Props {
|
||||
// Exports
|
||||
container_class_li?: string | Array<string>;
|
||||
// export let display_mode: string = 'default'; // 'default', 'compact', 'minimal', 'launcher'
|
||||
// event_session_id_random_li: Array<string>;
|
||||
event_session_obj_li?: Array<any>;
|
||||
link_to_type: string;
|
||||
link_to_id: string;
|
||||
// export let lq__event_presentation_obj
|
||||
log_lvl?: number;
|
||||
show_location_fields?: boolean;
|
||||
hide_session_code?: boolean;
|
||||
}
|
||||
|
||||
let {
|
||||
container_class_li = [],
|
||||
// event_session_id_random_li,
|
||||
event_session_obj_li = $bindable(),
|
||||
link_to_type,
|
||||
link_to_id,
|
||||
log_lvl = $bindable(0),
|
||||
show_location_fields = true,
|
||||
hide_session_code = false
|
||||
}: Props = $props();
|
||||
|
||||
// Imports
|
||||
import Comp_event_session_obj_tbl from './ae_comp__event_session_obj_tbl.svelte';
|
||||
|
||||
import { liveQuery } from 'dexie';
|
||||
import {
|
||||
events_loc,
|
||||
events_sess,
|
||||
events_slct,
|
||||
events_trigger
|
||||
} from '$lib/stores/ae_events_stores';
|
||||
import { db_events } from '$lib/ae_events/db_events';
|
||||
|
||||
$effect(() => {
|
||||
if (log_lvl) {
|
||||
console.log(`link_to_type: ${link_to_type}; link_to_id: ${link_to_id}`);
|
||||
}
|
||||
});
|
||||
|
||||
let {
|
||||
container_class_li = [],
|
||||
// event_session_id_random_li,
|
||||
event_session_obj_li = $bindable(),
|
||||
link_to_type,
|
||||
link_to_id,
|
||||
log_lvl = $bindable(0),
|
||||
show_location_fields = true,
|
||||
hide_session_code = false
|
||||
}: Props = $props();
|
||||
// Variables
|
||||
// let ae_promises: key_val = {};
|
||||
// let ae_tmp: key_val = {};
|
||||
// let ae_triggers: key_val = {};
|
||||
|
||||
// Imports
|
||||
import Comp_event_session_obj_tbl from './ae_comp__event_session_obj_tbl.svelte';
|
||||
let event_session_id_random_li: Array<string> = $state([]);
|
||||
|
||||
import { liveQuery } from 'dexie';
|
||||
import {
|
||||
events_loc,
|
||||
events_sess,
|
||||
events_slct,
|
||||
events_trigger
|
||||
} from '$lib/stores/ae_events_stores';
|
||||
import { db_events } from '$lib/ae_events/db_events';
|
||||
let dq__where_type_id_val = $derived(`${link_to_type}_id_random`);
|
||||
let dq__where_eq_id_val = $derived(link_to_id);
|
||||
|
||||
$effect(() => {
|
||||
if (log_lvl) {
|
||||
console.log(`link_to_type: ${link_to_type}; link_to_id: ${link_to_id}`);
|
||||
// *** Functions and Logic
|
||||
|
||||
// OPTIMIZATION: If event_session_obj_li is provided (from API/reports),
|
||||
// use it directly instead of fetching from IDB. The API returns fully
|
||||
// enriched data with all joined fields (location names, file counts, etc.)
|
||||
// that aren't available in the base IDB session table.
|
||||
let lq__event_session_obj_li = $derived(
|
||||
liveQuery(async () => {
|
||||
let results: any;
|
||||
|
||||
// If data is already provided (from API reports with joins), use it directly
|
||||
if (event_session_obj_li?.length) {
|
||||
if (log_lvl) {
|
||||
console.log(
|
||||
`LQ - Using provided event_session_obj_li (${event_session_obj_li.length} sessions with API joins)`
|
||||
);
|
||||
}
|
||||
return event_session_obj_li;
|
||||
}
|
||||
});
|
||||
|
||||
// Variables
|
||||
// let ae_promises: key_val = {};
|
||||
// let ae_tmp: key_val = {};
|
||||
// let ae_triggers: key_val = {};
|
||||
|
||||
let event_session_id_random_li: Array<string> = $state([]);
|
||||
|
||||
let dq__where_type_id_val = $derived(`${link_to_type}_id_random`);
|
||||
let dq__where_eq_id_val = $derived(link_to_id);
|
||||
|
||||
// *** Functions and Logic
|
||||
|
||||
// OPTIMIZATION: If event_session_obj_li is provided (from API/reports),
|
||||
// use it directly instead of fetching from IDB. The API returns fully
|
||||
// enriched data with all joined fields (location names, file counts, etc.)
|
||||
// that aren't available in the base IDB session table.
|
||||
let lq__event_session_obj_li = $derived(
|
||||
liveQuery(async () => {
|
||||
let results: any;
|
||||
|
||||
// If data is already provided (from API reports with joins), use it directly
|
||||
if (event_session_obj_li?.length) {
|
||||
if (log_lvl) {
|
||||
console.log(
|
||||
`LQ - Using provided event_session_obj_li (${event_session_obj_li.length} sessions with API joins)`
|
||||
);
|
||||
}
|
||||
return event_session_obj_li;
|
||||
// Otherwise fetch from IDB for link_to_type/link_to_id lookups
|
||||
if (link_to_type && link_to_id) {
|
||||
if (log_lvl) {
|
||||
console.log(
|
||||
`LQ - Fetching from IDB where: ${dq__where_type_id_val} = ${dq__where_eq_id_val}`
|
||||
);
|
||||
}
|
||||
event_session_id_random_li = [];
|
||||
results = await db_events.session
|
||||
.where(dq__where_type_id_val)
|
||||
.equals(dq__where_eq_id_val)
|
||||
.sortBy('name');
|
||||
} else {
|
||||
event_session_id_random_li = [];
|
||||
results = [];
|
||||
}
|
||||
|
||||
// Otherwise fetch from IDB for link_to_type/link_to_id lookups
|
||||
if (link_to_type && link_to_id) {
|
||||
if (log_lvl) {
|
||||
console.log(
|
||||
`LQ - Fetching from IDB where: ${dq__where_type_id_val} = ${dq__where_eq_id_val}`
|
||||
);
|
||||
}
|
||||
event_session_id_random_li = [];
|
||||
results = await db_events.session
|
||||
.where(dq__where_type_id_val)
|
||||
.equals(dq__where_eq_id_val)
|
||||
.sortBy('name');
|
||||
} else {
|
||||
event_session_id_random_li = [];
|
||||
results = [];
|
||||
// Check if results are different than the current session version stored under $events_slct
|
||||
if (
|
||||
$events_slct.event_session_obj_li &&
|
||||
JSON.stringify($events_slct.event_session_obj_li) !==
|
||||
JSON.stringify(results)
|
||||
) {
|
||||
$events_slct.event_session_obj_li = [...results];
|
||||
if (log_lvl) {
|
||||
console.log(
|
||||
`Session slct li stored version has changed for ID = ${$events_slct.journal_id}`,
|
||||
$events_slct.event_session_obj_li
|
||||
);
|
||||
}
|
||||
|
||||
// Check if results are different than the current session version stored under $events_slct
|
||||
if (
|
||||
$events_slct.event_session_obj_li &&
|
||||
JSON.stringify($events_slct.event_session_obj_li) !==
|
||||
JSON.stringify(results)
|
||||
) {
|
||||
$events_slct.event_session_obj_li = [...results];
|
||||
if (log_lvl) {
|
||||
console.log(
|
||||
`Session slct li stored version has changed for ID = ${$events_slct.journal_id}`,
|
||||
$events_slct.event_session_obj_li
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if (log_lvl > 1) {
|
||||
console.log(
|
||||
`Session slct li stored version has not changed for ID = ${$events_slct.journal_id}`
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if (log_lvl > 1) {
|
||||
console.log(
|
||||
`Session slct li stored version has not changed for ID = ${$events_slct.journal_id}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
return results;
|
||||
|
||||
// if (event_session_id_random_li.length) {
|
||||
// let results = await db_events.session
|
||||
// .bulkGet(event_session_id_random_li);
|
||||
// if (event_session_id_random_li.length) {
|
||||
// let results = await db_events.session
|
||||
// .bulkGet(event_session_id_random_li);
|
||||
|
||||
// return results;
|
||||
// } else if (link_to_type && link_to_id) {
|
||||
// console.log(`Trying where: ${dq__where_type_id_val}; equals: ${dq__where_eq_id_val}`);
|
||||
// let results = await db_events.session
|
||||
// .where(dq__where_type_id_val)
|
||||
// .equals(dq__where_eq_id_val)
|
||||
// .sortBy('name')
|
||||
// return results;
|
||||
// } else if (link_to_type && link_to_id) {
|
||||
// console.log(`Trying where: ${dq__where_type_id_val}; equals: ${dq__where_eq_id_val}`);
|
||||
// let results = await db_events.session
|
||||
// .where(dq__where_type_id_val)
|
||||
// .equals(dq__where_eq_id_val)
|
||||
// .sortBy('name')
|
||||
|
||||
// return results;
|
||||
// } else {
|
||||
// return null;
|
||||
// }
|
||||
})
|
||||
);
|
||||
// return results;
|
||||
// } else {
|
||||
// return null;
|
||||
// }
|
||||
})
|
||||
);
|
||||
</script>
|
||||
|
||||
{#if event_session_obj_li && event_session_obj_li?.length}
|
||||
@@ -138,10 +138,9 @@
|
||||
{lq__event_session_obj_li}
|
||||
{show_location_fields}
|
||||
{hide_session_code}
|
||||
{log_lvl}
|
||||
></Comp_event_session_obj_tbl>
|
||||
{log_lvl}></Comp_event_session_obj_tbl>
|
||||
{:else}
|
||||
<section class="grow px-1 md:px-2 pb-28 flex flex-col gap-1 items-center">
|
||||
<section class="flex grow flex-col items-center gap-1 px-1 pb-28 md:px-2">
|
||||
<p>No sessions available to show in table.</p>
|
||||
</section>
|
||||
{/if}
|
||||
|
||||
@@ -1,133 +1,134 @@
|
||||
<script lang="ts">
|
||||
import {
|
||||
ae_snip,
|
||||
ae_loc,
|
||||
ae_sess,
|
||||
ae_api,
|
||||
ae_trig,
|
||||
slct,
|
||||
slct_trigger
|
||||
} from '$lib/stores/ae_stores';
|
||||
import { TrendingUp, MapPin, Wrench, Search, GraduationCap, Plane, Settings } from '@lucide/svelte';
|
||||
import {
|
||||
ae_snip,
|
||||
ae_loc,
|
||||
ae_sess,
|
||||
ae_api,
|
||||
ae_trig,
|
||||
slct,
|
||||
slct_trigger
|
||||
} from '$lib/stores/ae_stores';
|
||||
import {
|
||||
TrendingUp,
|
||||
MapPin,
|
||||
Wrench,
|
||||
Search,
|
||||
GraduationCap,
|
||||
Plane,
|
||||
Settings
|
||||
} from '@lucide/svelte';
|
||||
|
||||
interface Props {
|
||||
// import { events_loc, events_sess, events_slct, events_trigger, events_trig_kv } from '$lib/stores/ae_events_stores';
|
||||
hide?: boolean;
|
||||
event_id?: null | string;
|
||||
ae_core?: boolean;
|
||||
events__launcher_id?: null | string; // event_location_id
|
||||
events__location_id?: null | string; // event_location_id
|
||||
events__locations?: boolean; // event_id
|
||||
// export let events__presenter_id: null|string = null; // event_presenter_id
|
||||
events__reports?: boolean; // event_id
|
||||
events__settings?: boolean; // event_id
|
||||
events__launcher_session_id?: null | string; // event_session_id to pass to launcher as ?session_id=
|
||||
events__session_id?: null | string; // event_session_id — used for "Back to Session" link only
|
||||
events__session_search?: boolean; // event_id
|
||||
events__launcher_extra_params?: string; // extra URL params appended to the launcher link (e.g. 'iframe=true&launcher_menu=hide')
|
||||
}
|
||||
interface Props {
|
||||
// import { events_loc, events_sess, events_slct, events_trigger, events_trig_kv } from '$lib/stores/ae_events_stores';
|
||||
hide?: boolean;
|
||||
event_id?: null | string;
|
||||
ae_core?: boolean;
|
||||
events__launcher_id?: null | string; // event_location_id
|
||||
events__location_id?: null | string; // event_location_id
|
||||
events__locations?: boolean; // event_id
|
||||
// export let events__presenter_id: null|string = null; // event_presenter_id
|
||||
events__reports?: boolean; // event_id
|
||||
events__settings?: boolean; // event_id
|
||||
events__launcher_session_id?: null | string; // event_session_id to pass to launcher as ?session_id=
|
||||
events__session_id?: null | string; // event_session_id — used for "Back to Session" link only
|
||||
events__session_search?: boolean; // event_id
|
||||
events__launcher_extra_params?: string; // extra URL params appended to the launcher link (e.g. 'iframe=true&launcher_menu=hide')
|
||||
}
|
||||
|
||||
let {
|
||||
hide = true,
|
||||
event_id = null,
|
||||
ae_core = false,
|
||||
events__launcher_id = null,
|
||||
events__launcher_session_id = null,
|
||||
events__launcher_extra_params = '',
|
||||
events__location_id = null,
|
||||
events__locations = false,
|
||||
events__reports = false,
|
||||
events__settings = false,
|
||||
events__session_id = null,
|
||||
events__session_search = false
|
||||
}: Props = $props();
|
||||
let {
|
||||
hide = true,
|
||||
event_id = null,
|
||||
ae_core = false,
|
||||
events__launcher_id = null,
|
||||
events__launcher_session_id = null,
|
||||
events__launcher_extra_params = '',
|
||||
events__location_id = null,
|
||||
events__locations = false,
|
||||
events__reports = false,
|
||||
events__settings = false,
|
||||
events__session_id = null,
|
||||
events__session_search = false
|
||||
}: Props = $props();
|
||||
|
||||
// Build launcher URL segments separately so the href template stays simple (avoids ternaries in href attr)
|
||||
let launcher_loc_seg = $derived(events__launcher_id ? `/${events__launcher_id}` : '');
|
||||
let launcher_sess_qry = $derived.by(() => {
|
||||
const parts: string[] = [];
|
||||
if (events__launcher_session_id) parts.push(`session_id=${events__launcher_session_id}`);
|
||||
if (events__launcher_extra_params) parts.push(events__launcher_extra_params);
|
||||
return parts.length ? `?${parts.join('&')}` : '';
|
||||
});
|
||||
// Build launcher URL segments separately so the href template stays simple (avoids ternaries in href attr)
|
||||
let launcher_loc_seg = $derived(
|
||||
events__launcher_id ? `/${events__launcher_id}` : ''
|
||||
);
|
||||
let launcher_sess_qry = $derived.by(() => {
|
||||
const parts: string[] = [];
|
||||
if (events__launcher_session_id)
|
||||
parts.push(`session_id=${events__launcher_session_id}`);
|
||||
if (events__launcher_extra_params)
|
||||
parts.push(events__launcher_extra_params);
|
||||
return parts.length ? `?${parts.join('&')}` : '';
|
||||
});
|
||||
</script>
|
||||
|
||||
<!-- This is for common navigation links. -->
|
||||
<div
|
||||
class="ae_comp__events_menu_nav w-full flex flex-row flex-wrap gap-1.5 items-center justify-between"
|
||||
class:hidden={hide}
|
||||
>
|
||||
class="ae_comp__events_menu_nav flex w-full flex-row flex-wrap items-center justify-between gap-1.5"
|
||||
class:hidden={hide}>
|
||||
<span
|
||||
class="ae_menu__navigation_options flex flex-row flex-wrap gap-0.5 items-center justify-around"
|
||||
>
|
||||
class="ae_menu__navigation_options flex flex-row flex-wrap items-center justify-around gap-0.5">
|
||||
<a
|
||||
href="/core"
|
||||
class="btn btn-sm mx-1 ae_btn_warning"
|
||||
class:hidden={!ae_core}
|
||||
>
|
||||
class="btn btn-sm ae_btn_warning mx-1"
|
||||
class:hidden={!ae_core}>
|
||||
<Settings size="1em" aria-hidden="true" />
|
||||
Æ Core
|
||||
</a>
|
||||
|
||||
<a
|
||||
href="/events/{event_id}/reports"
|
||||
class="btn btn-sm mx-1 ae_btn_info"
|
||||
class:hidden={!events__reports}
|
||||
>
|
||||
class="btn btn-sm ae_btn_info mx-1"
|
||||
class:hidden={!events__reports}>
|
||||
<TrendingUp size="1em" aria-hidden="true" />
|
||||
Pres Mgmt Reports
|
||||
</a>
|
||||
<a
|
||||
href="/events/{event_id}/locations"
|
||||
class="btn btn-sm mx-1 ae_btn_info"
|
||||
class:hidden={!events__locations}
|
||||
>
|
||||
class="btn btn-sm ae_btn_info mx-1"
|
||||
class:hidden={!events__locations}>
|
||||
<MapPin size="1em" aria-hidden="true" />
|
||||
Locations
|
||||
</a>
|
||||
<a
|
||||
href="/events/{event_id}/settings"
|
||||
class="btn btn-sm mx-1 ae_btn_warning"
|
||||
class:hidden={!events__settings}
|
||||
>
|
||||
class="btn btn-sm ae_btn_warning mx-1"
|
||||
class:hidden={!events__settings}>
|
||||
<Wrench size="1em" aria-hidden="true" />
|
||||
Admin Tools
|
||||
</a>
|
||||
</span>
|
||||
|
||||
<span
|
||||
class="ae_menu__navigation_options flex flex-row flex-wrap gap-0.5 items-center justify-around"
|
||||
>
|
||||
class="ae_menu__navigation_options flex flex-row flex-wrap items-center justify-around gap-0.5">
|
||||
<a
|
||||
href="/events/{event_id}/pres_mgmt"
|
||||
class="btn btn-sm mx-1 ae_btn_info"
|
||||
class:hidden={!events__session_search}
|
||||
>
|
||||
class="btn btn-sm ae_btn_info mx-1"
|
||||
class:hidden={!events__session_search}>
|
||||
<Search size="1em" aria-hidden="true" />
|
||||
Session Search
|
||||
</a>
|
||||
<a
|
||||
href="/events/{event_id}/session/{events__session_id}"
|
||||
class="btn btn-sm mx-1 ae_btn_info"
|
||||
class:hidden={!events__session_id}
|
||||
>
|
||||
class="btn btn-sm ae_btn_info mx-1"
|
||||
class:hidden={!events__session_id}>
|
||||
<GraduationCap size="1em" aria-hidden="true" />
|
||||
Back to Session
|
||||
</a>
|
||||
<!-- eslint-disable-next-line svelte/valid-compile -->
|
||||
<a
|
||||
href="/events/{event_id}/launcher{launcher_loc_seg}{launcher_sess_qry}"
|
||||
class="btn btn-sm mx-1 ae_btn_info"
|
||||
class:hidden={!event_id}
|
||||
>
|
||||
class="btn btn-sm ae_btn_info mx-1"
|
||||
class:hidden={!event_id}>
|
||||
<Plane size="1em" aria-hidden="true" />
|
||||
Launcher
|
||||
</a>
|
||||
<a
|
||||
href="/events/{event_id}/location/{events__location_id}"
|
||||
class="btn btn-sm mx-1 ae_btn_info"
|
||||
class:hidden={!events__location_id}
|
||||
>
|
||||
class="btn btn-sm ae_btn_info mx-1"
|
||||
class:hidden={!events__location_id}>
|
||||
<MapPin size="1em" aria-hidden="true" />
|
||||
Session Location
|
||||
</a>
|
||||
|
||||
@@ -1,43 +1,62 @@
|
||||
<script lang="ts">
|
||||
interface Props {
|
||||
hide?: boolean;
|
||||
}
|
||||
interface Props {
|
||||
hide?: boolean;
|
||||
}
|
||||
|
||||
let { hide = true }: Props = $props();
|
||||
let { hide = true }: Props = $props();
|
||||
|
||||
import {
|
||||
ae_snip,
|
||||
ae_loc,
|
||||
ae_sess,
|
||||
ae_api,
|
||||
ae_trig,
|
||||
slct,
|
||||
slct_trigger
|
||||
} from '$lib/stores/ae_stores';
|
||||
import {
|
||||
events_loc,
|
||||
events_sess,
|
||||
events_slct,
|
||||
events_trigger,
|
||||
events_trig_kv
|
||||
} from '$lib/stores/ae_events_stores';
|
||||
import { Ban, Barcode, CheckCircle, ChevronDown, ChevronUp, Eye, EyeOff, List, MapPin, Pencil, Plane, QrCode, Save, Send, Sparkles, StickyNote, ToggleLeft, ToggleRight, UserRound, Wand2 } from '@lucide/svelte';
|
||||
import {
|
||||
ae_snip,
|
||||
ae_loc,
|
||||
ae_sess,
|
||||
ae_api,
|
||||
ae_trig,
|
||||
slct,
|
||||
slct_trigger
|
||||
} from '$lib/stores/ae_stores';
|
||||
import {
|
||||
events_loc,
|
||||
events_sess,
|
||||
events_slct,
|
||||
events_trigger,
|
||||
events_trig_kv
|
||||
} from '$lib/stores/ae_events_stores';
|
||||
import {
|
||||
Ban,
|
||||
Barcode,
|
||||
CheckCircle,
|
||||
ChevronDown,
|
||||
ChevronUp,
|
||||
Eye,
|
||||
EyeOff,
|
||||
List,
|
||||
MapPin,
|
||||
Pencil,
|
||||
Plane,
|
||||
QrCode,
|
||||
Save,
|
||||
Send,
|
||||
Sparkles,
|
||||
StickyNote,
|
||||
ToggleLeft,
|
||||
ToggleRight,
|
||||
UserRound,
|
||||
Wand2
|
||||
} from '@lucide/svelte';
|
||||
</script>
|
||||
|
||||
<!-- New standard events module menu 2025-06-20 -->
|
||||
<div
|
||||
class="ae_comp__pres_mgmt_menu_opts w-full border-t border-gray-300 mt-1"
|
||||
class:hidden={hide}
|
||||
>
|
||||
<h2 class="text-sm font-semibold text-center pb-1">
|
||||
class="ae_comp__pres_mgmt_menu_opts mt-1 w-full border-t border-gray-300"
|
||||
class:hidden={hide}>
|
||||
<h2 class="pb-1 text-center text-sm font-semibold">
|
||||
<button
|
||||
type="button"
|
||||
onclick={() => {
|
||||
$events_loc.pres_mgmt.hide__menu_opts =
|
||||
!$events_loc.pres_mgmt.hide__menu_opts;
|
||||
}}
|
||||
class="btn btn-sm preset-tonal-info border border-info-500"
|
||||
>
|
||||
class="btn btn-sm preset-tonal-info border-info-500 border">
|
||||
{#if $events_loc.pres_mgmt.hide__menu_opts}
|
||||
<ChevronUp size="1em" class="m-1" />
|
||||
{:else}
|
||||
@@ -53,28 +72,24 @@
|
||||
</h2>
|
||||
|
||||
<div
|
||||
class="flex flex-row flex-wrap gap-1 items-center justify-between"
|
||||
class:hidden={$events_loc.pres_mgmt.hide__menu_opts}
|
||||
>
|
||||
class="flex flex-row flex-wrap items-center justify-between gap-1"
|
||||
class:hidden={$events_loc.pres_mgmt.hide__menu_opts}>
|
||||
{#if $ae_loc.authenticated_access}
|
||||
<div class="flex flex-col gap-1 items-end justify-center">
|
||||
<span class="flex flex-col gap-1 items-end justify-center">
|
||||
<div class="flex flex-col items-end justify-center gap-1">
|
||||
<span class="flex flex-col items-end justify-center gap-1">
|
||||
<!-- Max person select options -->
|
||||
<span
|
||||
class="flex flex-row gap-1 items-center justify-around w-full"
|
||||
>
|
||||
class="flex w-full flex-row items-center justify-around gap-1">
|
||||
<label
|
||||
class="text-sm w-32 text-right"
|
||||
for="qry_limit__people"
|
||||
>
|
||||
class="w-32 text-right text-sm"
|
||||
for="qry_limit__people">
|
||||
Max people:
|
||||
</label>
|
||||
<!-- Not using: $events_loc.pres_mgmt.qry_limit__people -->
|
||||
<select
|
||||
id="qry_limit__people"
|
||||
bind:value={$ae_loc.person.qry_limit__people}
|
||||
class="select w-20 text-sm preset-tonal-surface px-1"
|
||||
>
|
||||
class="select preset-tonal-surface w-20 px-1 text-sm">
|
||||
<option value="">-- not set --</option>
|
||||
<option value={25}>25</option>
|
||||
<option value={50}>50</option>
|
||||
@@ -91,12 +106,10 @@
|
||||
|
||||
<!-- Max presenters select options -->
|
||||
<span
|
||||
class="flex flex-row gap-1 items-center justify-around w-full"
|
||||
>
|
||||
class="flex w-full flex-row items-center justify-around gap-1">
|
||||
<label
|
||||
class="text-sm w-32 text-right"
|
||||
for="qry_limit__presenters"
|
||||
>
|
||||
class="w-32 text-right text-sm"
|
||||
for="qry_limit__presenters">
|
||||
Max presenters:
|
||||
</label>
|
||||
<select
|
||||
@@ -104,8 +117,7 @@
|
||||
bind:value={
|
||||
$events_loc.pres_mgmt.qry_limit__presenters
|
||||
}
|
||||
class="select w-20 text-sm preset-tonal-surface px-1"
|
||||
>
|
||||
class="select preset-tonal-surface w-20 px-1 text-sm">
|
||||
<option value="">-- not set --</option>
|
||||
<option value={25}>25</option>
|
||||
<option value={50}>50</option>
|
||||
@@ -123,12 +135,10 @@
|
||||
|
||||
<!-- Max sessions select options -->
|
||||
<span
|
||||
class="flex flex-row gap-1 items-center justify-around w-full"
|
||||
>
|
||||
class="flex w-full flex-row items-center justify-around gap-1">
|
||||
<label
|
||||
class="text-sm w-32 text-right"
|
||||
for="qry_limit__sessions"
|
||||
>
|
||||
class="w-32 text-right text-sm"
|
||||
for="qry_limit__sessions">
|
||||
Max sessions:
|
||||
</label>
|
||||
<select
|
||||
@@ -136,8 +146,7 @@
|
||||
bind:value={
|
||||
$events_loc.pres_mgmt.qry_limit__sessions
|
||||
}
|
||||
class="select w-20 text-sm preset-tonal-surface px-1"
|
||||
>
|
||||
class="select preset-tonal-surface w-20 px-1 text-sm">
|
||||
<option value="">-- not set --</option>
|
||||
<option value={25}>25</option>
|
||||
<option value={50}>50</option>
|
||||
@@ -150,19 +159,16 @@
|
||||
|
||||
<!-- Max files select options -->
|
||||
<span
|
||||
class="flex flex-row gap-1 items-center justify-around w-full"
|
||||
>
|
||||
class="flex w-full flex-row items-center justify-around gap-1">
|
||||
<label
|
||||
class="text-sm w-32 text-right"
|
||||
for="qry_limit__files"
|
||||
>
|
||||
class="w-32 text-right text-sm"
|
||||
for="qry_limit__files">
|
||||
Max files:
|
||||
</label>
|
||||
<select
|
||||
id="qry_limit__files"
|
||||
bind:value={$events_loc.pres_mgmt.qry_limit__files}
|
||||
class="select w-20 text-sm preset-tonal-surface px-1"
|
||||
>
|
||||
class="select preset-tonal-surface w-20 px-1 text-sm">
|
||||
<option value="">-- not set --</option>
|
||||
<option value={25}>25</option>
|
||||
<option value={50}>50</option>
|
||||
@@ -174,7 +180,7 @@
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<span class="flex flex-col gap-1 items-end justify-center">
|
||||
<span class="flex flex-col items-end justify-center gap-1">
|
||||
<!-- Toggle between the showing hidden sessions -->
|
||||
<!-- qry_hidden = all, not_hidden, hidden -->
|
||||
<button
|
||||
@@ -186,10 +192,13 @@
|
||||
$events_loc.pres_mgmt.qry_hidden = 'all';
|
||||
}
|
||||
}}
|
||||
class="btn btn-sm ae_btn_surface justify-between w-full text-center"
|
||||
title="Toggle between showing hidden sessions"
|
||||
>
|
||||
{#if $events_loc.pres_mgmt.qry_hidden == 'all'}<ToggleRight size="1em" class="m-1" />{:else}<ToggleLeft size="1em" class="m-1" />{/if}
|
||||
class="btn btn-sm ae_btn_surface w-full justify-between text-center"
|
||||
title="Toggle between showing hidden sessions">
|
||||
{#if $events_loc.pres_mgmt.qry_hidden == 'all'}<ToggleRight
|
||||
size="1em"
|
||||
class="m-1" />{:else}<ToggleLeft
|
||||
size="1em"
|
||||
class="m-1" />{/if}
|
||||
{#if $events_loc.pres_mgmt.qry_hidden == 'all'}
|
||||
<span class="grow">
|
||||
<EyeOff size="1em" class="m-1" />
|
||||
@@ -218,10 +227,13 @@
|
||||
$events_loc.pres_mgmt.qry_enabled = 'all';
|
||||
}
|
||||
}}
|
||||
class="btn btn-sm ae_btn_surface justify-between w-full text-center"
|
||||
title="Toggle between showing disabled sessions"
|
||||
>
|
||||
{#if $events_loc.pres_mgmt.qry_enabled == 'all'}<ToggleRight size="1em" class="m-1" />{:else}<ToggleLeft size="1em" class="m-1" />{/if}
|
||||
class="btn btn-sm ae_btn_surface w-full justify-between text-center"
|
||||
title="Toggle between showing disabled sessions">
|
||||
{#if $events_loc.pres_mgmt.qry_enabled == 'all'}<ToggleRight
|
||||
size="1em"
|
||||
class="m-1" />{:else}<ToggleLeft
|
||||
size="1em"
|
||||
class="m-1" />{/if}
|
||||
{#if $events_loc.pres_mgmt.qry_enabled == 'all'}
|
||||
<span class="grow">
|
||||
<Ban size="1em" class="m-1" />
|
||||
@@ -239,19 +251,18 @@
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class="flex flex-col flex-wrap gap-1 items-center justify-evenly">
|
||||
<div class="flex flex-col flex-wrap items-center justify-evenly gap-1">
|
||||
<button
|
||||
type="button"
|
||||
onclick={() => {
|
||||
$events_loc.pres_mgmt.save_search_text =
|
||||
!$events_loc.pres_mgmt.save_search_text;
|
||||
}}
|
||||
class="btn btn-sm justify-between w-full text-center"
|
||||
class="btn btn-sm w-full justify-between text-center"
|
||||
class:ae_btn_surface={$events_loc.pres_mgmt.save_search_text}
|
||||
class:ae_btn_surface_outlined={!$events_loc.pres_mgmt
|
||||
.save_search_text}
|
||||
title="Save the search text for this session search?"
|
||||
>
|
||||
title="Save the search text for this session search?">
|
||||
{#if $events_loc.pres_mgmt.save_search_text}
|
||||
<ToggleRight size="1em" class="m-1" />
|
||||
<span class="grow">
|
||||
@@ -274,8 +285,7 @@
|
||||
onclick={() => {
|
||||
$events_loc.pres_mgmt.hide__session_msg = true;
|
||||
}}
|
||||
class="btn btn-sm ae_btn_surface justify-between w-full text-center"
|
||||
>
|
||||
class="btn btn-sm ae_btn_surface w-full justify-between text-center">
|
||||
<ToggleRight size="1em" class="m-1" />
|
||||
<span class="grow">
|
||||
<StickyNote size="1em" class="m-1" />
|
||||
@@ -288,8 +298,7 @@
|
||||
onclick={() => {
|
||||
$events_loc.pres_mgmt.hide__session_msg = false;
|
||||
}}
|
||||
class="btn btn-sm ae_btn_surface_outlined justify-between w-full text-center"
|
||||
>
|
||||
class="btn btn-sm ae_btn_surface_outlined w-full justify-between text-center">
|
||||
<ToggleLeft size="1em" class="m-1" />
|
||||
<span class="grow">
|
||||
<StickyNote size="1em" class="m-1" />
|
||||
@@ -307,8 +316,7 @@
|
||||
onclick={() => {
|
||||
$events_loc.pres_mgmt.hide__session_code = true;
|
||||
}}
|
||||
class="btn btn-sm ae_btn_surface justify-between w-full text-center"
|
||||
>
|
||||
class="btn btn-sm ae_btn_surface w-full justify-between text-center">
|
||||
<ToggleRight size="1em" class="m-1" />
|
||||
<span class="grow">
|
||||
<Barcode size="1em" class="m-1" />
|
||||
@@ -321,8 +329,7 @@
|
||||
onclick={() => {
|
||||
$events_loc.pres_mgmt.hide__session_code = false;
|
||||
}}
|
||||
class="btn btn-sm ae_btn_surface_outlined justify-between w-full text-center"
|
||||
>
|
||||
class="btn btn-sm ae_btn_surface_outlined w-full justify-between text-center">
|
||||
<ToggleLeft size="1em" class="m-1" />
|
||||
<span class="grow">
|
||||
<Barcode size="1em" class="m-1" />
|
||||
@@ -333,17 +340,16 @@
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-1 items-center justify-center">
|
||||
<div class="flex flex-col items-center justify-center gap-1">
|
||||
{#if $ae_loc.trusted_access}
|
||||
<div class="flex flex-col gap-1 items-center justify-center">
|
||||
<div class="flex flex-col items-center justify-center gap-1">
|
||||
{#if $events_loc.pres_mgmt.show__copy_access_link}
|
||||
<button
|
||||
type="button"
|
||||
onclick={() => {
|
||||
$events_loc.pres_mgmt.show__copy_access_link = false;
|
||||
}}
|
||||
class="btn btn-sm w-full ae_btn_surface"
|
||||
>
|
||||
class="btn btn-sm ae_btn_surface w-full">
|
||||
<ToggleRight size="1em" class="m-1" />
|
||||
Showing Copy Access Link
|
||||
</button>
|
||||
@@ -353,8 +359,7 @@
|
||||
onclick={() => {
|
||||
$events_loc.pres_mgmt.show__copy_access_link = true;
|
||||
}}
|
||||
class="btn btn-sm w-full ae_btn_surface_outlined"
|
||||
>
|
||||
class="btn btn-sm ae_btn_surface_outlined w-full">
|
||||
<ToggleLeft size="1em" class="m-1" />
|
||||
Show Copy Access Link?
|
||||
</button>
|
||||
@@ -366,8 +371,7 @@
|
||||
onclick={() => {
|
||||
$events_loc.pres_mgmt.show__email_access_link = false;
|
||||
}}
|
||||
class="btn btn-sm w-full ae_btn_surface"
|
||||
>
|
||||
class="btn btn-sm ae_btn_surface w-full">
|
||||
<ToggleRight size="1em" class="m-1" />
|
||||
Showing Email Access Link
|
||||
</button>
|
||||
@@ -377,8 +381,7 @@
|
||||
onclick={() => {
|
||||
$events_loc.pres_mgmt.show__email_access_link = true;
|
||||
}}
|
||||
class="btn btn-sm w-full ae_btn_surface_outlined"
|
||||
>
|
||||
class="btn btn-sm ae_btn_surface_outlined w-full">
|
||||
<ToggleLeft size="1em" class="m-1" />
|
||||
Show Email Access Link?
|
||||
</button>
|
||||
@@ -387,16 +390,15 @@
|
||||
{/if}
|
||||
|
||||
{#if $ae_loc.authenticated_access}
|
||||
<div class="flex flex-col gap-1 items-end justify-center">
|
||||
<div class="flex flex-col items-end justify-center gap-1">
|
||||
{#if $events_loc.pres_mgmt.show_content__session_qr}
|
||||
<button
|
||||
type="button"
|
||||
onclick={() => {
|
||||
$events_loc.pres_mgmt.show_content__session_qr = false;
|
||||
}}
|
||||
class="btn btn-sm ae_btn_surface justify-between w-full text-center"
|
||||
title="Showing Session QR Code"
|
||||
>
|
||||
class="btn btn-sm ae_btn_surface w-full justify-between text-center"
|
||||
title="Showing Session QR Code">
|
||||
<ToggleRight size="1em" class="m-1" />
|
||||
<span class="grow">
|
||||
<QrCode size="1em" class="m-1" />
|
||||
@@ -409,9 +411,8 @@
|
||||
onclick={() => {
|
||||
$events_loc.pres_mgmt.show_content__session_qr = true;
|
||||
}}
|
||||
class="btn btn-sm ae_btn_surface_outlined justify-between w-full text-center"
|
||||
title="Show Session QR Code"
|
||||
>
|
||||
class="btn btn-sm ae_btn_surface_outlined w-full justify-between text-center"
|
||||
title="Show Session QR Code">
|
||||
<ToggleLeft size="1em" class="m-1" />
|
||||
<span class="grow">
|
||||
<QrCode size="1em" class="m-1" />
|
||||
@@ -426,9 +427,8 @@
|
||||
onclick={() => {
|
||||
$events_loc.pres_mgmt.show_content__presenter_qr = false;
|
||||
}}
|
||||
class="btn btn-sm ae_btn_surface justify-between w-full text-center"
|
||||
title="Showing Presenter QR Code"
|
||||
>
|
||||
class="btn btn-sm ae_btn_surface w-full justify-between text-center"
|
||||
title="Showing Presenter QR Code">
|
||||
<ToggleRight size="1em" class="m-1" />
|
||||
<span class="grow">
|
||||
<QrCode size="1em" class="m-1" />
|
||||
@@ -441,9 +441,8 @@
|
||||
onclick={() => {
|
||||
$events_loc.pres_mgmt.show_content__presenter_qr = true;
|
||||
}}
|
||||
class="btn btn-sm ae_btn_surface_outlined justify-between w-full text-center"
|
||||
title="Show Presenter QR Code"
|
||||
>
|
||||
class="btn btn-sm ae_btn_surface_outlined w-full justify-between text-center"
|
||||
title="Show Presenter QR Code">
|
||||
<ToggleLeft size="1em" class="m-1" />
|
||||
<span class="grow">
|
||||
<QrCode size="1em" class="m-1" />
|
||||
@@ -456,7 +455,7 @@
|
||||
</div>
|
||||
|
||||
{#if $ae_loc.authenticated_access}
|
||||
<div class="flex flex-col gap-1 items-center justify-center">
|
||||
<div class="flex flex-col items-center justify-center gap-1">
|
||||
<!-- Show/Hide launcher links (new version) -->
|
||||
<button
|
||||
type="button"
|
||||
@@ -464,9 +463,12 @@
|
||||
$events_loc.pres_mgmt.hide__launcher_link =
|
||||
!$events_loc.pres_mgmt.hide__launcher_link;
|
||||
}}
|
||||
class="btn btn-sm ae_btn_surface justify-between w-full text-center"
|
||||
>
|
||||
{#if $events_loc.pres_mgmt.hide__launcher_link}<ToggleLeft size="1em" class="m-1" />{:else}<ToggleRight size="1em" class="m-1" />{/if}
|
||||
class="btn btn-sm ae_btn_surface w-full justify-between text-center">
|
||||
{#if $events_loc.pres_mgmt.hide__launcher_link}<ToggleLeft
|
||||
size="1em"
|
||||
class="m-1" />{:else}<ToggleRight
|
||||
size="1em"
|
||||
class="m-1" />{/if}
|
||||
<span class="grow">
|
||||
<Plane size="1em" class="m-1" />
|
||||
{$events_loc.pres_mgmt.hide__launcher_link
|
||||
@@ -482,9 +484,12 @@
|
||||
$events_loc.pres_mgmt.hide__launcher_link_legacy =
|
||||
!$events_loc.pres_mgmt.hide__launcher_link_legacy;
|
||||
}}
|
||||
class="btn btn-sm ae_btn_surface justify-between w-full text-center"
|
||||
>
|
||||
{#if $events_loc.pres_mgmt.hide__launcher_link_legacy}<ToggleLeft size="1em" class="m-1" />{:else}<ToggleRight size="1em" class="m-1" />{/if}
|
||||
class="btn btn-sm ae_btn_surface w-full justify-between text-center">
|
||||
{#if $events_loc.pres_mgmt.hide__launcher_link_legacy}<ToggleLeft
|
||||
size="1em"
|
||||
class="m-1" />{:else}<ToggleRight
|
||||
size="1em"
|
||||
class="m-1" />{/if}
|
||||
<span class="grow">
|
||||
<Send size="1em" class="m-1" />
|
||||
{$events_loc.pres_mgmt.hide__launcher_link_legacy
|
||||
@@ -500,9 +505,12 @@
|
||||
$events_loc.pres_mgmt.hide__location_link =
|
||||
!$events_loc.pres_mgmt.hide__location_link;
|
||||
}}
|
||||
class="btn btn-sm ae_btn_surface justify-between w-full text-center"
|
||||
>
|
||||
{#if $events_loc.pres_mgmt.hide__location_link}<ToggleLeft size="1em" class="m-1" />{:else}<ToggleRight size="1em" class="m-1" />{/if}
|
||||
class="btn btn-sm ae_btn_surface w-full justify-between text-center">
|
||||
{#if $events_loc.pres_mgmt.hide__location_link}<ToggleLeft
|
||||
size="1em"
|
||||
class="m-1" />{:else}<ToggleRight
|
||||
size="1em"
|
||||
class="m-1" />{/if}
|
||||
<span class="grow">
|
||||
<MapPin size="1em" class="m-1" />
|
||||
{$events_loc.pres_mgmt.hide__location_link
|
||||
@@ -519,10 +527,13 @@
|
||||
!$events_loc.pres_mgmt
|
||||
.hide__session_li_location_field;
|
||||
}}
|
||||
class="btn btn-sm ae_btn_surface justify-between w-full text-center"
|
||||
title="Toggle showing the Location column in session lists and tables"
|
||||
>
|
||||
{#if $events_loc.pres_mgmt.hide__session_li_location_field}<ToggleLeft size="1em" class="m-1" />{:else}<ToggleRight size="1em" class="m-1" />{/if}
|
||||
class="btn btn-sm ae_btn_surface w-full justify-between text-center"
|
||||
title="Toggle showing the Location column in session lists and tables">
|
||||
{#if $events_loc.pres_mgmt.hide__session_li_location_field}<ToggleLeft
|
||||
size="1em"
|
||||
class="m-1" />{:else}<ToggleRight
|
||||
size="1em"
|
||||
class="m-1" />{/if}
|
||||
<span class="grow">
|
||||
<!-- <span class="fas fa-door-open m-1"></span> -->
|
||||
{$events_loc.pres_mgmt.hide__session_li_location_field
|
||||
@@ -538,10 +549,13 @@
|
||||
$events_loc.pres_mgmt.hide__session_li_poc_field =
|
||||
!$events_loc.pres_mgmt.hide__session_li_poc_field;
|
||||
}}
|
||||
class="btn btn-sm ae_btn_surface justify-between w-full text-center"
|
||||
title="Toggle showing the POC column in session lists and tables"
|
||||
>
|
||||
{#if $events_loc.pres_mgmt.hide__session_li_poc_field}<ToggleLeft size="1em" class="m-1" />{:else}<ToggleRight size="1em" class="m-1" />{/if}
|
||||
class="btn btn-sm ae_btn_surface w-full justify-between text-center"
|
||||
title="Toggle showing the POC column in session lists and tables">
|
||||
{#if $events_loc.pres_mgmt.hide__session_li_poc_field}<ToggleLeft
|
||||
size="1em"
|
||||
class="m-1" />{:else}<ToggleRight
|
||||
size="1em"
|
||||
class="m-1" />{/if}
|
||||
<span class="grow">
|
||||
<!-- <span class="fas fa-user-tie m-1"></span> -->
|
||||
{$events_loc.pres_mgmt.hide__session_li_poc_field
|
||||
@@ -552,8 +566,7 @@
|
||||
|
||||
<!-- These are related to more content showing in lists. -->
|
||||
<span
|
||||
class="flex flex-col flex-wrap gap-1 items-center justify-evenly"
|
||||
>
|
||||
class="flex flex-col flex-wrap items-center justify-evenly gap-1">
|
||||
{#if $events_loc.pres_mgmt.show_content__session_files}
|
||||
<button
|
||||
type="button"
|
||||
@@ -561,8 +574,7 @@
|
||||
onclick={() => {
|
||||
$events_loc.pres_mgmt.show_content__session_files = false;
|
||||
}}
|
||||
class="btn btn-sm ae_btn_surface justify-between w-full text-center"
|
||||
>
|
||||
class="btn btn-sm ae_btn_surface w-full justify-between text-center">
|
||||
<ToggleRight size="1em" class="m-1" />
|
||||
<span class="grow">
|
||||
<List size="1em" class="m-1" />
|
||||
@@ -576,8 +588,7 @@
|
||||
onclick={() => {
|
||||
$events_loc.pres_mgmt.show_content__session_files = true;
|
||||
}}
|
||||
class="btn btn-sm ae_btn_surface_outlined justify-between w-full text-center"
|
||||
>
|
||||
class="btn btn-sm ae_btn_surface_outlined w-full justify-between text-center">
|
||||
<ToggleLeft size="1em" class="m-1" />
|
||||
<span class="grow">
|
||||
<List size="1em" class="m-1" />
|
||||
@@ -593,8 +604,7 @@
|
||||
onclick={() => {
|
||||
$events_loc.pres_mgmt.show_content__session_presentations = false;
|
||||
}}
|
||||
class="btn btn-sm ae_btn_surface justify-between w-full text-center"
|
||||
>
|
||||
class="btn btn-sm ae_btn_surface w-full justify-between text-center">
|
||||
<ToggleRight size="1em" class="m-1" />
|
||||
<span class="grow">
|
||||
<List size="1em" class="m-1" />
|
||||
@@ -608,8 +618,7 @@
|
||||
onclick={() => {
|
||||
$events_loc.pres_mgmt.show_content__session_presentations = true;
|
||||
}}
|
||||
class="btn btn-sm ae_btn_surface_outlined justify-between w-full text-center"
|
||||
>
|
||||
class="btn btn-sm ae_btn_surface_outlined w-full justify-between text-center">
|
||||
<ToggleLeft size="1em" class="m-1" />
|
||||
<span class="grow">
|
||||
<List size="1em" class="m-1" />
|
||||
@@ -622,8 +631,7 @@
|
||||
{/if}
|
||||
|
||||
<div
|
||||
class="flex flex-row flex-wrap gap-1 items-center justify-evenly max-w-56"
|
||||
>
|
||||
class="flex max-w-56 flex-row flex-wrap items-center justify-evenly gap-1">
|
||||
{#if $ae_loc?.trusted_access}
|
||||
{#if $ae_loc?.edit_mode}
|
||||
<button
|
||||
@@ -631,9 +639,8 @@
|
||||
onclick={() => {
|
||||
$ae_loc.edit_mode = false;
|
||||
}}
|
||||
class="btn btn-sm ae_btn_warning justify-between w-full text-center"
|
||||
title="Turn off edit mode"
|
||||
>
|
||||
class="btn btn-sm ae_btn_warning w-full justify-between text-center"
|
||||
title="Turn off edit mode">
|
||||
<ToggleRight size="1em" class="m-1" />
|
||||
<span class="grow">
|
||||
<Pencil size="1em" class="m-1" />
|
||||
@@ -646,9 +653,8 @@
|
||||
onclick={() => {
|
||||
$ae_loc.edit_mode = true;
|
||||
}}
|
||||
class="btn btn-sm ae_btn_warning_outlined justify-between w-full text-center"
|
||||
title="Turn on edit mode"
|
||||
>
|
||||
class="btn btn-sm ae_btn_warning_outlined w-full justify-between text-center"
|
||||
title="Turn on edit mode">
|
||||
<ToggleLeft size="1em" class="m-1" />
|
||||
<span class="grow">
|
||||
<UserRound size="1em" class="m-1" />
|
||||
@@ -663,9 +669,8 @@
|
||||
onclick={() => {
|
||||
$ae_loc.adv_mode = false;
|
||||
}}
|
||||
class="btn btn-sm ae_btn_warning justify-between w-full text-center"
|
||||
title="Turn off advanced mode"
|
||||
>
|
||||
class="btn btn-sm ae_btn_warning w-full justify-between text-center"
|
||||
title="Turn off advanced mode">
|
||||
<ToggleRight size="1em" class="m-1" />
|
||||
<span class="grow">
|
||||
<Sparkles size="1em" class="m-1" />
|
||||
@@ -678,9 +683,8 @@
|
||||
onclick={() => {
|
||||
$ae_loc.adv_mode = true;
|
||||
}}
|
||||
class="btn btn-sm ae_btn_warning_outlined justify-between w-full text-center"
|
||||
title="Turn on advanced mode"
|
||||
>
|
||||
class="btn btn-sm ae_btn_warning_outlined w-full justify-between text-center"
|
||||
title="Turn on advanced mode">
|
||||
<ToggleLeft size="1em" class="m-1" />
|
||||
<span class="grow">
|
||||
<Wand2 size="1em" class="m-1" />
|
||||
|
||||
Reference in New Issue
Block a user