Prettier for Events as a whole. Everything else under that primary directory.

This commit is contained in:
Scott Idem
2026-03-24 12:16:44 -04:00
parent 6e67534454
commit 6018a94499
11 changed files with 1459 additions and 1465 deletions

View File

@@ -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'}&times;
</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>