feat(pres_mgmt): File Downloads report with clean filename presets

New report at Pres Mgmt > Reports > File Downloads. Groups all event files
by session and presenter, with 10 filename format presets (original, session
code/date/name combos, presenter variants). Per-file Download button and Copy
Link button using hosted_file endpoint for ?key= auth support.

Also fixes direct download links in element_manage_event_file_li and the
hosted_files download button — event_file endpoint does not yet propagate
?key= auth internally, so all direct links now use hosted_file endpoint
which supports it today.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Scott Idem
2026-06-10 14:19:25 -04:00
parent 1b81b8873c
commit 6b122a065e
6 changed files with 597 additions and 25 deletions

View File

@@ -186,16 +186,13 @@ let is_url_file = $derived.by(() => {
let direct_download_url = $derived.by(() => {
if (!show_direct_download || !hosted_file_obj) return '';
// IMPORTANT: For Direct Link Mode, we MUST use the V3 Action endpoint to support Random String IDs.
// Legacy endpoints often expect integer IDs and will return 404 for string IDs.
// Always use the hosted_file endpoint — it supports ?key= auth and resolves event_file
// IDs automatically via Redis. The event_file endpoint's ?key= support is not yet deployed.
const file_id =
hosted_file_obj.event_file_id ||
hosted_file_obj.hosted_file_id ||
hosted_file_obj.event_file_id ||
hosted_file_id;
const obj_type_path = hosted_file_obj.event_file_id
? 'event_file'
: 'hosted_file';
return `${$ae_api.base_url}/v3/action/${obj_type_path}/${file_id}/download?filename=${ae_util.clean_filename(final_filename)}&key=${$ae_api.account_id}`;
return `${$ae_api.base_url}/v3/action/hosted_file/${file_id}/download?filename=${ae_util.clean_filename(final_filename)}&key=${$ae_api.account_id}`;
});
async function handle_click() {

View File

@@ -317,7 +317,7 @@ async function handle_convert_pdf_to_image(event_file_obj: key_val) {
</span>
<MyClipboard
value={encodeURI(
`${$ae_api.base_url}/v3/action/event_file/${event_file_obj?.event_file_id}/download?filename=${ae_util.clean_filename(event_file_obj?.filename)}&key=${$ae_api.account_id}`
`${$ae_api.base_url}/v3/action/hosted_file/${event_file_obj?.hosted_file_id}/download?filename=${ae_util.clean_filename(event_file_obj?.filename)}&key=${$ae_api.account_id}`
)}
btn_text="Copy Original"
btn_title="Copy the direct download link to the clipboard."
@@ -326,10 +326,10 @@ async function handle_convert_pdf_to_image(event_file_obj: key_val) {
<MyClipboard
value={encodeURI(
`${$ae_api.base_url}/v3/action/event_file/${event_file_obj?.event_file_id}/download?filename=${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}&key=${$ae_api.account_id}`
`${$ae_api.base_url}/v3/action/hosted_file/${event_file_obj?.hosted_file_id}/download?filename=${ae_util.clean_filename(event_file_obj?.event_session_code ?? '')}_${ae_util.clean_filename(event_file_obj?.event_presentation_name ?? event_file_obj?.event_session_name ?? '').substring(0, 30)}_${ae_util.clean_filename(event_file_obj?.event_presenter_full_name ?? '')}.${event_file_obj?.extension}&key=${$ae_api.account_id}`
)}
btn_text="Copy Renamed"
btn_title="Copy the renamed download link to the clipboard."
btn_title="Copy the renamed download link to the clipboard. Format: [session-code]_[presentation-name]_[presenter-name].[ext]"
btn_class="btn btn-xs preset-tonal-warning hover:preset-filled-warning-500"
></MyClipboard>
</div>

View File

@@ -244,6 +244,7 @@ export interface PresMgmtSessState {
recent_files: string | null;
presenters_agree: string | null;
presenters_biography: string | null;
file_downloads: string | null;
};
rpt__session_no_files: boolean;
rpt__session_poc_agree: boolean;
@@ -414,7 +415,8 @@ export const pres_mgmt_sess_defaults: PresMgmtSessState = {
status_rpt: {
recent_files: null,
presenters_agree: null,
presenters_biography: null
presenters_biography: null,
file_downloads: null
},
rpt__session_no_files: true,
rpt__session_poc_agree: false,