Added ability to upload files individually to get the % uploaded. Added show/hide of manage files for sessions and presenters. Other clean up.

This commit is contained in:
Scott Idem
2024-08-13 16:42:10 -04:00
parent d5dbeeabf7
commit 00fcd8e747
9 changed files with 227 additions and 67 deletions

View File

@@ -172,6 +172,8 @@ let events_local_data_struct: key_val = {
show_content__session_help: true,
show_content__session_search_help: true,
show_content__presenter_page_help: true,
show_content__presenter_view: null,
show_content__session_view: null,
show_menu__session: null,

View File

@@ -18,7 +18,8 @@ string_snippets['classes__core_menu__button_warning'] = 'btn btn-sm mx-1 variant
// string_snippets['classes__events_pres_mgmt_menu'] = 'flex flex-col items-center space-y-1 border border-blue-200 rounded-md py-1 px-2 hover:bg-blue-100 transition-all duration-700 hover:duration-300';
string_snippets['classes__events_pres_mgmt_menu'] = 'w-full flex flex-col items-center gap-1 border border-gray-200 rounded-md p-1 hover:bg-gray-100 transition-all duration-700 hover:duration-300';
string_snippets['classes__events_pres_mgmt_menu__button'] = 'btn btn-sm mx-1 variant-soft-tertiary text-info-300 hover:text-info-800';
string_snippets['classes__events_pres_mgmt_menu__button'] = 'btn btn-sm mx-1 variant-soft-tertiary text-info-300 hover:text-info-800 hover:variant-filled-tertiary';
string_snippets['classes__events_pres_mgmt_menu__button_special'] = 'btn btn-sm mx-1 variant-ghost-tertiary text-info-300 hover:text-info-800 hover:variant-filled-tertiary';
string_snippets['classes__events_pres_mgmt_menu__button_highlight'] = 'btn btn-sm mx-1 variant-filled-tertiary text-info-300 hover:text-info-800';
string_snippets['classes__events_pres_mgmt_menu__button_warning'] = 'btn btn-sm mx-1 variant-soft-warning text-info-300 hover:text-info-800';

View File

@@ -7,7 +7,7 @@ import { ae_util } from '$lib/ae_utils';
import { core_func } from '$lib/ae_core_functions';
import { ae_loc, ae_sess, ae_api, ae_trig, slct, slct_trigger } from '$lib/ae_stores';
export let element_id = 'svelte_input_file_element';
// export let element_id = 'svelte_input_file_element';
export let container_class_li: string[] = [];
export let table_class_li: string[] = ['table', 'table-sm', 'table-striped', 'table-hover' , 'text-sm'];
@@ -20,9 +20,9 @@ export let input_file_list: any = null;
export let file_list_status: null|string = null;
export let processed_file_list: any[] = [];
const dispatch = createEventDispatcher();
// const dispatch = createEventDispatcher();
let input_file_list_processed: any[] = [];
// let input_file_list_processed: any[] = [];
onMount(() => {
console.log('** Element Mounted: ** Element Input File');
@@ -37,22 +37,26 @@ $: if (input_file_list) {
// console.log(result);
if (!result || !result.length) {
processed_file_list = [];
file_list_status = 'none';
}
// Save the results to the file upload list to be displayed as a table.
input_file_list_processed = result; // Includes file hash
// input_file_list_processed = result; // Includes file hash
dispatch(
'input_file_list_updated',
{
element_id: element_id,
input_file_list: input_file_list,
input_file_list_processed: result, // Includes file hash
}
);
// dispatch(
// 'input_file_list_updated',
// {
// element_id: element_id,
// input_file_list: input_file_list,
// input_file_list_processed: result, // Includes file hash
// }
// );
});
} else {
processed_file_list = [];
file_list_status = 'none';
}
@@ -298,9 +302,9 @@ function remove_file_from_filelist(index) {
</div>
{/if}
<!-- {#await input_file_list_processed} -->
<!-- {#await processed_file_list} -->
<!-- {:then} -->
{#if use_selected_file_table && input_file_list_processed && input_file_list_processed.length}
{#if use_selected_file_table && processed_file_list && processed_file_list.length}
<strong>Files selected for upload</strong>
<table class="slct_file_list text-sm {table_class_li.join(' ')}">
<thead>
@@ -314,7 +318,7 @@ function remove_file_from_filelist(index) {
<th>Hash</th>
</tr>
</thead>
{#each input_file_list_processed as file_list_item, file_index}
{#each processed_file_list as file_list_item, file_index}
<tbody>
<tr>
<td class="file_remove">
@@ -332,9 +336,9 @@ function remove_file_from_filelist(index) {
class:bg-pink-200={file_list_item.warning_size}
>
{file_list_item.file_size_string}
<!-- {#if $ae_sess.api_upload_kv[link_to_id]}
<span class="text-xs">({$ae_sess.api_upload_kv[link_to_id].percent_completed}%)</span>
{/if} -->
{#if $ae_sess.api_upload_kv[file_list_item.hash_sha256]}
<span class="text-xs">({$ae_sess.api_upload_kv[file_list_item.hash_sha256].percent_completed}%)</span>
{/if}
</td>
<!-- <td class="file_type" class:warning_file_untrusted_extension={file_list_item.warning_untrusted_extension} class:warning_file_legacy_extension={file_list_item.warning_legacy_extension}>{file_list_item.type}</td> -->
<td

View File

@@ -12,6 +12,7 @@ import { api } from '$lib/api';
import { ae_snip, ae_loc, ae_sess, ae_api, ae_trig, slct, slct_trigger } from '$lib/ae_stores';
import { events_loc, events_sess, events_slct, events_trigger } from '$lib/ae_events_stores';
import { events_func } from '$lib/ae_events_functions';
import { tick } from 'svelte';
// Exports
@@ -20,13 +21,16 @@ export let link_to_type: string;
export let link_to_id: string;
export let input_name = 'file_list';
export let multiple: boolean = false;
export let multiple: boolean = true;
export let required: boolean = true;
export let accept: string = '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';
export let input_class_li: string[] = ['file_drop_area'];
export let table_class_li: string[] = ['table', 'table-sm', 'table-striped', 'table-hover' , 'text-sm'];
export let upload_complete: boolean = false;
export let submit_status: null|string = null;
// Local Variables
let task_id = link_to_id;
@@ -42,22 +46,41 @@ async function handle_submit_form_files(event) {
$events_sess.files.disable_submit__event_file_obj = true;
$events_sess.files.submit_status = 'saving';
submit_status = 'saving';
upload_complete = false;
let hosted_file_results;
if (event.target[input_element_id].files.length > 0) {
task_id = link_to_id; // Ideally this should be the file hash, but we may be uploading multiple files at once. This should be done with a loop instead?
hosted_file_results = await handle_input_upload_files(event.target[input_element_id].files, task_id);
// Loop through each file and upload them individually in event.target[input_element_id].files
// The task_id should be the file hash.
// processed_file_list[i] has the file hash_sha256, hash_sha256_match, warnings, uploaded, uploaded_bytes, filename, and file_size_bytes.
for (let i = 0; i < event.target[input_element_id].files.length; i++) {
let tmp_file = event.target[input_element_id].files[i];
if (hosted_file_results) {
console.log(`hosted_file_results:`, hosted_file_results);
} else {
console.log(`hosted_file_results:`, hosted_file_results);
task_id = $events_sess.files.processed_file_list[i].hash_sha256;
hosted_file_results = await handle_input_upload_files([tmp_file], task_id);
if (hosted_file_results) {
console.log(`hosted_file_results:`, hosted_file_results);
} else {
console.log(`hosted_file_results:`, hosted_file_results);
}
}
// hosted_file_results = await handle_input_upload_files(event.target[input_element_id].files, task_id);
$events_sess.files.processed_file_list = [];
$events_sess = $events_sess;
event.target.reset();
// await tick();
}
$events_sess.files.disable_submit__event_file_obj = false;
$events_sess.files.submit_status = 'saved';
submit_status = 'saved';
upload_complete = true;
}
@@ -154,11 +177,11 @@ async function handle_input_upload_files(input_upload_files, task_id) {
console.log(error);
return false;
})
.finally(function (event_file_id) {
.finally( function () {
// $events_sess.files.files_uploading_count--;
$slct_trigger = 'load__event_file_obj_li';
return event_file_id;
// return event_file_id;
});
console.log(ae_promises.upload__hosted_file_obj);
@@ -177,10 +200,22 @@ async function handle_input_upload_files(input_upload_files, task_id) {
class:hidden={!$ae_loc.trusted_access}
class="modal-form {$ae_loc.hub.classes__form} flex flex-col gap-1 items-center justify-center w-full"
>
{#await ae_promises.upload__hosted_file_obj}
<div class="text-lg flex flex-row gap-1 items-center justify-center">
<span class="fas fa-spinner fa-spin m-1"></span>
<span class="">
Uploading
{#if $ae_sess.api_upload_kv[task_id]}
{$ae_sess.api_upload_kv[task_id].percent_completed}%
{/if}
</span>
</div>
{/await}
<label
for="ae_comp__event_files_upload__input"
class="svelte_input_file_label text-center"
class:hidden={$events_sess.files.disable_submit__event_file_obj}
>
<div>
<span class="fas fa-upload"></span>
@@ -204,6 +239,7 @@ async function handle_input_upload_files(input_upload_files, task_id) {
{accept}
name={input_name}
class="svelte_input_file_element {input_class_li.join(' ')}"
class:hidden={$events_sess.files.disable_submit__event_file_obj}
/>
<Element_input_files_tbl
@@ -223,8 +259,8 @@ async function handle_input_upload_files(input_upload_files, task_id) {
<span class="fas fa-spinner fa-spin m-1"></span>
<span class="">
Uploading
{#if $ae_sess.api_upload_kv[link_to_id]}
{$ae_sess.api_upload_kv[link_to_id].percent_completed}%
{#if $ae_sess.api_upload_kv[task_id]}
{$ae_sess.api_upload_kv[task_id].percent_completed}%
{/if}
</span>
{:then}

View File

@@ -17,6 +17,8 @@ import { ae_snip, ae_loc, ae_sess, ae_api, ae_trig, slct, slct_trigger } from '$
import { events_loc, events_sess, events_slct, events_trigger } from '$lib/ae_events_stores';
import { events_func } from '$lib/ae_events_functions';
import Comp_event_files_upload from './../../ae_comp__event_files_upload.svelte';
import Element_manage_event_file_li from '$lib/element_manage_event_file_li.svelte';
import Form_agree from './../../form_agree.svelte';
import Presenter_view from './../../presenter_view.svelte';
import Presenter_page_menu from './../../presenter_page_menu.svelte';
@@ -48,6 +50,10 @@ let lq__event_presentation_obj = liveQuery(
() => db_events.presentations.get(ae_acct.slct.event_presentation_id)
);
if (!$ae_loc.authenticated_access && $events_loc.pres_mgmt.show_content__presenter_view) {
$events_loc.pres_mgmt.show_content__presenter_view = null;
}
// Functions and Logic
</script>
@@ -65,36 +71,65 @@ let lq__event_presentation_obj = liveQuery(
md:container h-full mx-auto flex flex-col gap-1 py-1 px-2 pb-16"
>
<Presenter_page_menu
data={data}
lq__event_presenter_obj={lq__event_presenter_obj}
/>
{#if !$lq__event_presenter_obj}
<span class="fas fa-spinner fa-spin mx-1"></span>
<span>Loading...</span>
{:else}
<!-- {$lq__event_presenter_obj?.full_name} -->
{/if}
<span>Loading presenter information...</span>
<!-- <hr class="w-full border border-gray-200" /> -->
{:else if $lq__event_presenter_obj?.enable || $ae_loc.trusted_access}
<!-- {#await $events_slct.event_presenter_obj}
<span class="fas fa-spinner fa-spin text-xl text-blue-500"></span>
{:then result} -->
<h2 class="h2 text-center rounded-md p-2 bg-gray-300">
{@html $lq__event_presenter_obj?.full_name ?? ae_snip.html__not_set}
</h2>
{#if !$events_loc.pres_mgmt.show_content__presenter_view || $events_loc.pres_mgmt.show_content__presenter_view == 'default'}
<Presenter_view
lq__event_presenter_obj={lq__event_presenter_obj}
lq__event_presentation_obj={lq__event_presentation_obj}
/>
<!-- {:catch error}
<div class="text-red-800">
<span class="fas fa-exclamation-triangle text-xl"></span>
<span>Error: {error.message}</span>
</div>
{/await} -->
<!-- {$events_slct.event_presentation_id ?? 'Unknown ID'} -->
{:else if $events_loc.pres_mgmt.show_content__presenter_view == 'manage_files' && $ae_loc.authenticated_access}
<div>
<h3 class="h5">
<span class="fas fa-upload m-1"></span>
Manage and Upload Session Files:
</h3>
<Comp_event_files_upload
link_to_type="event_presenter"
link_to_id={$lq__event_presenter_obj.event_presenter_id}
/>
<div class="overflow-x-auto w-max max-w-full">
<Element_manage_event_file_li
link_to_type={'event_presenter'}
link_to_id={$lq__event_presenter_obj?.event_presenter_id_random}
allow_basic={$events_loc.auth__kv.presenter[$lq__event_presenter_obj.event_presenter_id_random] || $events_loc.auth__kv.presenter[$lq__event_presenter_obj?.event_presenter_id_random]}
allow_moderator={$events_loc.auth__kv.presenter[$lq__event_presenter_obj.event_presenter_id_random]}
container_class_li={''}
/>
</div>
</div>
{/if}
{:else}
<div class="bg-red-100 p-4 border border-red-200 rounded-md">
<h2 class="h3">
<span class="fas fa-exclamation-triangle text-red-500 m-1"></span>
Presenter Disabled
</h2>
<p>
This presenter is currently disabled. Please contact the event organizer for more information.
</p>
</div>
{/if}
</section>

View File

@@ -46,6 +46,33 @@ let ae_triggers: key_val = {};
<span
class="ae_menu__object_options flex flex-row items-center justify-around"
>
<!-- Button to toggle between the regular presenter view and managing presenter files -->
<button
type="button"
on:click={() => {
if ($events_loc.pres_mgmt.show_content__presenter_view == 'manage_files') {
$events_loc.pres_mgmt.show_content__presenter_view = null;
} else {
$events_loc.pres_mgmt.show_content__presenter_view = 'manage_files';
}
}}
class="{ae_snip.classes__events_pres_mgmt_menu__button_special}"
class:hidden={!$ae_loc.authenticated_access}
title="Manage files for the presenter"
>
{#if $events_loc.pres_mgmt.show_content__presenter_view == 'manage_files'}
<span class="fas fa-info m-1"></span>
<!-- View Details -->
Presenter Info
{:else}
<span class="fas fa-file-archive m-1"></span>
Presenter Files
<!-- <span> -->
{$lq__event_presenter_obj?.file_count ? `(${$lq__event_presenter_obj?.file_count})` : ''}
<!-- </span> -->
{/if}
</button>
<button
type="button"
on:click={() => {

View File

@@ -3,6 +3,7 @@
export let data: any;
// console.log(`ae_events_pres_mgmt event [slug] +page.svelte data:`, data);
// Imports
import { onMount } from 'svelte';
import { clipboard } from '@skeletonlabs/skeleton';
@@ -10,8 +11,8 @@ import { clipboard } from '@skeletonlabs/skeleton';
import type { key_val } from '$lib/ae_stores';
import { ae_util } from '$lib/ae_utils';
import { api, send_email } from '$lib/api';
import Element_ae_crud from '$lib/element_ae_crud.svelte';
import Element_data_store from '$lib/element_data_store.svelte';
// import Element_ae_crud from '$lib/element_ae_crud.svelte';
// import Element_data_store from '$lib/element_data_store.svelte';
let ae_promises: key_val = {};
let ae_tmp: key_val = {};
@@ -25,12 +26,14 @@ import { events_loc, events_sess, events_slct, events_trigger, events_trig_kv }
import { events_func } from '$lib/ae_events_functions';
import Comp_event_files_upload from './../../ae_comp__event_files_upload.svelte';
import Element_manage_event_file_li from '$lib/element_manage_event_file_li.svelte';
import Session_view from './../../session_view.svelte';
import Session_page_menu from './../../session_page_menu.svelte';
// import Sign_in_out from './../../sign_in_out.svelte';
import { browser } from '$app/environment';
// Variables
if (browser) {
console.log('Browser environment detected.');
}
@@ -101,7 +104,11 @@ let lq__auth__event_presenter_obj = liveQuery(
$slct.person_obj_kv = {}; // This is intended for the POC lookup list when generated.
if (!$ae_loc.authenticated_access && $events_loc.pres_mgmt.show_content__session_view) {
$events_loc.pres_mgmt.show_content__session_view = null;
}
// Functions and Logic
onMount(() => {
console.log('Events Session [slug]: +page.svelte');
@@ -239,34 +246,53 @@ onMount(() => {
lq__auth__event_presenter_obj={lq__auth__event_presenter_obj}
/>
{#if !$lq__event_session_obj}
<div>
<span class="fas fa-spinner fa-spin m-1"></span>
<span>Loading session information...</span>
</div>
{:else if $lq__event_session_obj?.enable || $ae_loc.trusted_access}
<Session_view
event_session_id={$lq__event_session_obj.event_session_id}
lq__event_session_obj={lq__event_session_obj}
lq__auth__event_presenter_obj={lq__auth__event_presenter_obj}
lq__event_presentation_obj_li={lq__event_presentation_obj_li}
/>
{#if $ae_loc.trusted_access}
<div>
<h3 class="h4">
<span class="fas fa-upload m-1"></span>
Upload Session Files:
</h3>
<Comp_event_files_upload
link_to_type="event_session"
link_to_id={$lq__event_session_obj.event_session_id}
{:else if $lq__event_session_obj?.enable || $ae_loc.trusted_access}
<h2 class="h2 text-center rounded-md p-2 bg-gray-300">
{@html $lq__event_session_obj?.name ?? ae_snip.html__not_set}
</h2>
{#if !$events_loc.pres_mgmt.show_content__session_view || $events_loc.pres_mgmt.show_content__session_view == 'default'}
<Session_view
event_session_id={$lq__event_session_obj.event_session_id}
lq__event_session_obj={lq__event_session_obj}
lq__auth__event_presenter_obj={lq__auth__event_presenter_obj}
lq__event_presentation_obj_li={lq__event_presentation_obj_li}
/>
{:else if $events_loc.pres_mgmt.show_content__session_view == 'manage_files' && $ae_loc.trusted_access}
<div>
<h3 class="h5">
<span class="fas fa-upload m-1"></span>
Manage and Upload Session Files:
</h3>
<Comp_event_files_upload
link_to_type="event_session"
link_to_id={$lq__event_session_obj.event_session_id}
/>
<div class="overflow-x-auto w-max max-w-full">
<Element_manage_event_file_li
link_to_type={'event_session'}
link_to_id={$lq__event_session_obj?.event_session_id_random}
allow_basic={$events_loc.auth__kv.session[$lq__event_session_obj.event_session_id_random] || $events_loc.auth__kv.session[$lq__event_session_obj?.event_session_id_random]}
allow_moderator={$events_loc.auth__kv.session[$lq__event_session_obj.event_session_id_random]}
container_class_li={''}
/>
</div>
</div>
{/if}
{:else}
<div class="bg-red-100 p-4 border border-red-200 rounded-md">
<h2 class="h3">
<span class="fas fa-exclamation-triangle text-red-500 m-1"></span>
@@ -276,7 +302,9 @@ onMount(() => {
This session is currently disabled. Please contact the event organizer for more information.
</p>
</div>
{/if}
</section>

View File

@@ -31,7 +31,7 @@ let ae_triggers: key_val = {};
class="flex flex-row flex-wrap gap-1 items-center justify-around w-full">
<span
class="ae_menu__navigation_options"
class="ae_menu__navigation_options flex flex-row items-center justify-around"
>
<a href="/events_pres_mgmt/event/{$lq__event_session_obj?.event_id_random}" class="{ae_snip.classes__events_pres_mgmt_menu__button}">
<span class="fas fa-arrow-left m-1"></span>
@@ -42,6 +42,33 @@ let ae_triggers: key_val = {};
<span
class="ae_menu__object_options"
>
<!-- Button to toggle between the regular session view and managing session files -->
<button
type="button"
on:click={() => {
if ($events_loc.pres_mgmt.show_content__session_view == 'manage_files') {
$events_loc.pres_mgmt.show_content__session_view = null;
} else {
$events_loc.pres_mgmt.show_content__session_view = 'manage_files';
}
}}
class="{ae_snip.classes__events_pres_mgmt_menu__button_special}"
class:hidden={!$ae_loc.authenticated_access}
title="Manage files for the session"
>
{#if $events_loc.pres_mgmt.show_content__session_view == 'manage_files'}
<span class="fas fa-users m-1"></span>
<!-- View Details -->
Session Presenters
{:else}
<span class="fas fa-file-archive m-1"></span>
Session Files
<!-- <span> -->
{$lq__event_session_obj?.file_count ? `(${$lq__event_session_obj?.file_count})` : ''}
<!-- </span> -->
{/if}
</button>
<button
type="button"
on:click={() => {

View File

@@ -96,9 +96,9 @@ $: if ($lq__event_session_obj) {
{#if $lq__event_session_obj}
<h2 class="h2 text-center rounded-md p-2 bg-gray-300">
<!-- <h2 class="h2 text-center rounded-md p-2 bg-gray-300">
{@html $lq__event_session_obj?.name ?? ae_snip.html__not_set}
</h2>
</h2> -->
<!-- Information about the session -->
<section>