Changes from before AAPOR

This commit is contained in:
Scott Idem
2024-05-20 17:24:23 -04:00
parent f72d7be5b2
commit fa58d1accb
13 changed files with 609 additions and 21 deletions

View File

@@ -196,6 +196,9 @@ export let ae_app_session_data_struct: key_val = {
},
'testing': {},
},
'download': {},
'download_li': {},
};
// console.log(`AE Stores - App Session Storage Data:`, ae_app_session_data_struct);
export let ae_sess = writable(ae_app_session_data_struct);

View File

@@ -309,6 +309,17 @@ export let get_object = async function get_object(
console.log('GET Blob Timestamp:', progressEvent.timeStamp, 'Total:', progressEvent.total, 'Loaded:', progressEvent.loaded, 'Percent Completed', percent_completed);
temp_get_blob_percent_completed = percent_completed;
// WARNING: This needs to be tied to an object type and ID. This is a temporary solution.
try {
window.postMessage({
type: 'api_download_blob', endpoint: endpoint, filename: filename, size_total: progressEvent.total, size_loaded: progressEvent.loaded, percent_completed: percent_completed
},
'*'
);
} catch (error) {
console.log('Error posting message to window:', error);
}
}
}
)
@@ -330,6 +341,17 @@ export let get_object = async function get_object(
filename = 'unknown_file.ext';
}
// WARNING: This needs to be tied to an object type and ID. This is a temporary solution.
try {
window.postMessage({
type: 'api_download_blob', endpoint: endpoint, filename: filename, size_total: 0, size_loaded: 0, percent_completed: 100
},
'*'
);
} catch (error) {
console.log('Error posting message to window:', error);
}
if (auto_download) {
if (log_lvl) {
console.log(`Auto Download: ${filename}`);

View File

@@ -199,6 +199,48 @@ onMount(() => {
$slct.sponsorship_cfg_id = data.url.searchParams.get('sponsorship_cfg_id');
$ae_loc.mod.sponsorships.cfg_id = data.url.searchParams.get('sponsorship_cfg_id');
}
// TESTING TESTING TESTING
// WARNING: This needs to be tied to an object type and ID. This is a temporary solution.
$ae_sess.download = {
'endpoint': '/event/file/abc123/download',
'filename': 'example.txt',
'size_total': 0,
'size_loaded': 0,
'percent_completed': 0,
};
window.addEventListener('message', function(event) {
console.log('Message received in root +layout.svelte:');
console.log(event);
if (event.data.type == 'api_download_blob') {
console.log('Download blob (file) message received:', event.data);
// Get the event_file_id from the event.data.endpoint value.
// Example: /event/file/abc123/download
let endpoint = event.data.endpoint;
// let event_file_id = endpoint.split('/')[3];
// ae_downloads[event_file_id] = {
$ae_sess.download = {
'endpoint': endpoint,
'filename': event.data.filename,
'size_total': event.data.size_total,
'size_loaded': event.data.size_loaded,
'percent_completed': event.data.percent_completed,
};
// let event_file_id = event.data.event_file_id;
// let filename = event.data.filename;
// let auto_download = event.data.auto_download;
// ae_promises[event_file_id]
// ae_promises[event_file_id] = download_event_file({ 'event_file_id': event_file_id, 'return_file': true, filename: filename, auto_download: auto_download, log_lvl: 1 });
}
});
});
</script>

View File

@@ -0,0 +1,89 @@
<script lang="ts">
/** @type {import('./$types').LayoutData} */
export let data: any;
import { goto } from '$app/navigation';
import { onMount } from 'svelte';
import type { Writable } from 'svelte/store';
import { localStorageStore } from '@skeletonlabs/skeleton';
import type { key_val } from '$lib/ae_stores';
// import { ae_util } from '$lib/ae_utils';
import { api } from '$lib/api';
import { ae_loc, ae_sess, ae_api, slct } from '$lib/ae_stores';
import { events_loc, events_slct, events_trigger } from '$lib/ae_events_stores';
// import Element_data_store from '$lib/element_data_store.svelte';
$events_loc.qry__enabled = 'enabled';
$events_loc.qry__hidden = 'not_hidden';
$events_loc.qry__limit = 15;
$events_loc.qry__offset = 0;
// Quickly save the data passed from the parent(s) to the Svelte stores, localStorage, and other.
$slct.account_id = data.account_id;
console.log(`$slct.account_id = `, $slct.account_id);
let ae_acct = data[$slct.account_id];
console.log(`ae_acct = `, ae_acct);
$events_slct.event_id = ae_acct.slct.event_id;
$events_slct.event_obj = ae_acct.slct.event_obj;
let ae_promises: key_val = {};
onMount(() => {
console.log('Events - Presentation Management: +layout.svelte');
});
</script>
<svelte:head>
<title>Events - Presentation Management - {$events_loc.title ?? 'Æ loading...'}</title>
</svelte:head>
<section
class="submenu flex flex-row justify-center"
class:hidden={$ae_loc.iframe}
>
<span class="btn-group variant-soft-secondary px-4 py-2">
{#each Object.entries(data.submenu) as [key, item]}
<!-- <a href="/settings/{item.slug}">{item.title}</a> -->
<!-- class:hidden={!$ae_loc.trusted_access && item.access} -->
{#if item.disable}
<button
title={item.title}
class="hover:variant-ghost-secondary"
class:hidden={(!$ae_loc.trusted_access && item.access === 'trusted') || (!$ae_loc.administrator_access && item.access === 'administrator' || item.hide)}
disabled={item.disable}
on:click={() => {
// window.location(item.href);
// href={item.href}
// invalidateAll
goto(item.href, { });
}}
>
{item.name}
</button>
{:else}
<a
href={item.href}
title={item.title}
class="hover:variant-ghost-secondary"
class:hidden={(!$ae_loc.trusted_access && item.access === 'trusted') || (!$ae_loc.administrator_access && item.access === 'administrator' || item.hide)}
class:disabled={item.disable}
>
{item.name}
</a>
{/if}
{/each}
</span>
</section>
<slot></slot>

View File

@@ -0,0 +1,46 @@
/** @type {import('./$types').LayoutLoad} */
console.log(`ae_events_pres_mgmt +layout.ts start`);
import { events_func } from '$lib/ae_events_functions';
export async function load({ parent }) {
let data = await parent();
// console.log(`ae_events_pres_mgmt +layout.ts data:`, data);
let account_id = data.account_id;
let ae_acct = data[account_id];
console.log(`ae_acct = `, ae_acct);
if (!account_id) {
console.log(`events_pres_mgmt +layout.ts: The account_id was not found in the data!!!`);
return false;
}
let event_id = ae_acct.slct.event_id;
if (!event_id) {
console.log(`events_pres_mgmt +layout.ts: The event_id was not found in the data!!!`);
return false;
}
let load_event_obj = events_func.handle_load_ae_obj_id__event({api_cfg: ae_acct.api, event_id: event_id, try_cache: false});
ae_acct.slct.event_obj = load_event_obj;
let submenu = {
main: {name: 'Main', href: '/events_pres_mgmt', access: false},
// manage: {name: 'Manage', href: '/events_pres_mgmt/manage', access: 'administrator', disable: true, hide: true},
locations: {name: 'Locations', href: '/events_pres_mgmt/locations', access: false, disable: false, hide: false},
};
data.submenu = submenu
// WARNING: Precaution against shared data between sites and sessions.
data[account_id] = ae_acct;
return data;
}
// export const prerender = false;
// export const prerender = true;

View File

@@ -0,0 +1,64 @@
<script lang="ts">
export let data: any;
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 { api } from '$lib/api';
import { ae_loc, ae_sess, ae_api, slct, slct_trigger } from '$lib/ae_stores';
import { events_loc, events_slct, events_trigger } from '$lib/ae_events_stores';
import { ae_util } from '$lib/ae_utils';
import Element_data_store from '$lib/element_data_store.svelte';
onMount(() => {
console.log('Events - Presentation Management: +page.svelte');
console.log('ae_ slct:', $slct);
let href_url = window.location.href;
// console.log(href_url);
$ae_loc.href_url = href_url;
// console.log(`$ae_loc.href_url = `, $ae_loc.href_url);
});
</script>
<section class="ae_events_pres_mgmt md:container h-full mx-auto">
<h2 class="h3">Presentation Management for {$events_slct.name} ({$events_slct.event_id})</h2>
<h3 class="h4">Restricted Access</h3>
<p>Accessing the presentation management system is currently restricted</p>
<Element_data_store
ds_code="events__pres_mgmt__overview"
ds_type="html"
for_type="event"
for_id={$events_slct.event_id}
display="block"
class_li="p-2"
/>
<!-- <Element_data_store
ds_code="events__pres_mgmt__example"
ds_type="html"
for_type="event"
for_id={$events_slct.event_id}
ds_name="Default: Events - Presentation Management Example"
store="local"
display="block"
class_li="variant-ghost-surface p-2"
try_cache={true}
show_edit={false}
/> -->
</section>
<style lang="postcss">
</style>

View File

@@ -0,0 +1,6 @@
/** @type {import('./$types').PageLoad} */
export function load() {
return {
ae_events_pres_mgmt_page_ts: true,
};
}

View File

@@ -0,0 +1,142 @@
<script lang="ts">
/** @type {import('./$types').PageData} */
export let data: any;
// console.log(`ae_events_pres_mgmt event [slug] +page.svelte data:`, data);
import { onMount } from 'svelte';
import { goto, invalidate, pushState, replaceState } from '$app/navigation';
import { clipboard, FileDropzone, getModalStore, localStorageStore, ProgressRadial, RadioGroup, RadioItem, TabGroup, Tab, TabAnchor } from '@skeletonlabs/skeleton';
import type { key_val } from '$lib/ae_stores';
import { ae_util } from '$lib/ae_utils';
import { api } from '$lib/api';
import { liveQuery } from "dexie";
import { db_events } from "$lib/db_events";
import { 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';
// Quickly save the data passed from the parent(s) to the Svelte stores, localStorage, and other.
$slct.account_id = data.account_id;
console.log(`$slct.account_id = `, $slct.account_id);
let ae_acct = data[$slct.account_id];
console.log(`ae_acct = `, ae_acct);
$events_slct.event_id = ae_acct.slct.event_id;
$events_slct.event_obj = ae_acct.slct.event_obj;
$events_slct.event_session_obj_li = ae_acct.slct.event_session_obj_li;
// import Leads_add_scan from './leads_add_scan.svelte';
// import Sessions_list from './sessions_list.svelte';
// import Leads_manage from './leads_manage.svelte';
// import Leads_payment from './leads_payment.svelte';
// let param_slug_event_id = data.params.slug;
let event_obj = liveQuery(
() => db_events.events.get($events_slct.event_id)
// () => db_events.events.get(param_slug_event_id)
// () => db_events.events.toArray()
// () => db_events.events
// .where('id_random')
// .equals($events_slct.event_id)
// // .orderBy('name')
// // .offset(10).limit(5)
// .toArray()
);
let event_obj_v2 = db_events.events.get($events_slct.event_id);
// Load the Event Obj with ID based on the slug param.
// $events_slct.event_id = param_slug_event_id;
// console.log('Selected Event ID:', $events_slct.event_id);
// $events_trigger = 'load__event_obj';
let license_submit_results: Promise<any>|key_val;
if (!$events_loc.leads.tab) {
$events_loc.leads.tab = {};
$events_loc.leads.tab[$events_slct.event_id] = 'start';
}
if (!$events_loc.leads.auth_exhibit_kv) {
$events_loc.leads.auth_exhibit_kv = {};
}
if ($events_loc.leads.auth_exhibit_kv && $events_loc.leads.auth_exhibit_kv[$events_slct.event_id]) {
console.log('Logged in using shared exhibit staff passcode.');
if ($events_loc.leads.auth_exhibit_kv[$events_slct.event_id].key) {
console.log(`Using the license key: ${$events_loc.leads.auth_exhibit_kv[$events_slct.event_id].key}`);
} else {
console.log('License key (email) not used.');
$events_loc.leads.tab[$events_slct.event_id] = 'start';
}
} else {
console.log('Not logged in using shared exhibit staff passcode.');
$events_loc.leads.tab[$events_slct.event_id] = 'start';
}
onMount(() => {
console.log('Events Leads Exhibit [slug]: +page.svelte');
// console.log(`ae_events_leads exhibit [slug] +page.svelte data:`, data);
if (!$events_slct.event_id) {
console.log(`No ID! Nothing to show. Try setting the ID again.`);
$events_slct.event_id = $events_slct.event_id;
}
});
// console.log(`$ae_loc = `, $ae_loc);
</script>
<section
class="ae_events_pres_mgmt_event md:container h-full mx-auto flex flex-col items-center space-y-4 pt-0 pb-8"
>
{#if $events_slct.event_id && $event_obj}
Nothing to see
{/if}
</section>
<style lang="postcss">
/* Use the div.ae_quick_modal_container to block background clicks when using the section.ae_quick_popover. */
div.ae_quick_modal_container {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 100;
background-color: hsla(0, 0%, 0%, .5);
}
/* The section.ae_quick_popover should be above the rest of the content and centered on the page. */
section.ae_quick_popover {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 100;
background-color: hsla(0, 0%, 100%, .95);
padding: 1rem;
border-radius: .5rem;
box-shadow: 0 0 1rem hsla(0, 0%, 0%, .5);
min-height: 30%;
min-width: 80%;
}
</style>

View File

@@ -0,0 +1,53 @@
/** @type {import('./$types').PageLoad} */
console.log(`ae_events_pres_mgmt_event [slug] +page.ts start`);
import { events_func } from '$lib/ae_events_functions';
export async function load({ parent }) { // route
// console.log(`ae_events_pres_mgmt_event +page.ts data.params:`, params);
// console.log(`ae_events_pres_mgmt_event +page.ts data.route:`, route);
// console.log(`ae_events_pres_mgmt_event +page.ts data.url:`, url);
let data = await parent();
// console.log(`ae_events_pres_mgmt_event +page.ts data:`, data);
let account_id = data.account_id;
let ae_acct = data[account_id];
console.log(`ae_acct = `, ae_acct);
if (!account_id) {
console.log(`events_pres_mgmt_event [slug] +page.ts: The account_id was not found in the data!!!`);
return false;
}
data.ae_events_pres_mgmt_event_slug_page_ts = true;
// let param_slug_event_id = data.params.slug;
let event_id = data.params.slug;
if (!event_id) {
console.log(`events_pres_mgmt_event [slug] +layout.ts: The event_id was not found in the data.params.slug!!!`);
return false;
}
ae_acct.slct.event_id = event_id;
let load_event_obj = events_func.handle_load_ae_obj_id__event({api_cfg: ae_acct.api, event_id: event_id, try_cache: false});
ae_acct.slct.event_obj = await load_event_obj;
let load_event_session_obj_li = events_func.handle_load_ae_obj_li__event_session({
api_cfg: ae_acct.api,
event_id: event_id,
params: {enabled: 'all', qry__limit: 550},
try_cache: false
});
console.log(`load_event_session_obj_li = `, load_event_session_obj_li);
ae_acct.slct.event_session_obj_li = load_event_session_obj_li;
// WARNING: Precaution against shared data between sites and sessions.
data[account_id] = ae_acct;
return data;
}

View File

@@ -401,7 +401,7 @@ async function handle_load_ae_obj_id__event_presenter({event_presenter_id, try_c
});
}}
class="btn btn-sm variant-ghost-primary w-48 mb-1 export_data_btn"
class="btn btn-sm variant-ghost-warning w-42 mb-1 export_data_btn text-xs"
title={`Download sponsorship data for ${$ae_loc.account_name}`}
>
{#await ae_promises.download__sponsorship_export}
@@ -412,7 +412,7 @@ async function handle_load_ae_obj_id__event_presenter({event_presenter_id, try_c
{:then}
<!-- Done? -->
{/await}
<span class="fas fa-download mx-1"></span> Export Data
<span class="fas fa-download mx-1"></span> Export All Data
</button>
{/if}
</section>

View File

@@ -181,15 +181,15 @@ async function handle_load_ae_obj_li__sponsorship({account_id, try_cache=true})
if ($ae_loc.administrator_access) {
enabled = 'all';
hidden = 'all';
// hidden = 'all';
limit = 150;
} else if ($ae_loc.trusted_access) {
enabled = 'enabled';
hidden = 'not_hidden';
// hidden = 'not_hidden';
limit = 100;
} else {
enabled = 'enabled';
hidden = 'not_hidden';
// hidden = 'not_hidden';
limit = 25;
}
@@ -424,6 +424,58 @@ function send_guest_list_email() {
body_html: body_html,
});
}
function generate_guest_list_csv(ae_obj_li) {
console.log(`*** generate_guest_list_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 = ['Sponsor', 'Level', 'POC', 'Guest', 'Title', 'Affiliations', 'ADA', 'Dietary', 'Comments'];
csv_data.push(csv_columns);
for (let i = 0; i < ae_obj_li.length; i++) {
if (ae_obj_li[i].guest_li_json && ae_obj_li[i].guest_li_json.length > 0) {
for (let j = 0; j < ae_obj_li[i].guest_li_json.length; j++) {
let csv_row = [];
csv_row.push(ae_obj_li[i].name);
csv_row.push(ae_obj_li[i].level_num);
csv_row.push(ae_obj_li[i].poc_json.full_name ?? ae_obj_li[i].poc_json.given_name);
csv_row.push(ae_obj_li[i].guest_li_json[j].full_name);
csv_row.push(ae_obj_li[i].guest_li_json[j].title ?? '');
csv_row.push(ae_obj_li[i].guest_li_json[j].affiliations ?? '');
csv_row.push(ae_obj_li[i].guest_li_json[j].ada ?? '');
csv_row.push(ae_obj_li[i].guest_li_json[j].dietary ?? '');
csv_row.push(ae_obj_li[i].guest_li_json[j].comments ?? '');
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', `CHOW_2024_Sponsor_Hub_guest_list_${ae_util.iso_datetime_formatter()}.csv`);
download_link.setAttribute('style', 'display: none;')
download_link.textContent = 'Download CSV';
// document.querySelector('body').appendChild(download_link);
document.getElementById('download_csv_container').appendChild(download_link);
// Automatically download the file
download_link.click();
return csv_data;
}
</script>
@@ -436,7 +488,9 @@ function send_guest_list_email() {
</h1>
</header>
<section>
<section
class="flex flex-col items-center space-y-2"
>
<button
class="btn variant-ghost-primary"
on:click={() => {
@@ -453,11 +507,14 @@ function send_guest_list_email() {
Start Sponsor Submission Form
</button>
{#if $ae_loc.trusted_access}
<span>
<button
type="button"
on:click={() => {
if (!confirm('Download data exported to an Excel file?')) {
if (!confirm('Download all data exported to an Excel file?')) {
return false;
}
ae_promises.download__sponsorships_export = core_func.handle_download_export__obj_type({
@@ -473,22 +530,21 @@ function send_guest_list_email() {
});
}}
class="btn btn-sm variant-ghost-primary w-48 mb-1 export_data_btn"
class="btn btn-sm variant-ghost-warning w-42 mb-1 export_data_btn text-xs"
title={`Download sponsorship data for ${$ae_loc.account_name}`}
>
{#await ae_promises.download__sponsorship_export}
<span class="fas fa-spinner fa-spin"></span>
<!-- <span class="loading-text">
Downloading...
</span> -->
<span class="fas fa-spinner fa-spin"></span>
{:then}
<!-- Done? -->
{/await}
<span class="fas fa-download mx-1"></span> Export Data
<span class="fas fa-download mx-1"></span> Export All Data
{#if $ae_sess.download && $ae_sess.download.size_total > $ae_sess.download.size_loaded}
{$ae_sess.download.percent_completed}%
{/if}
</button>
<button
<!-- <button
class="btn btn-sm variant-ghost-primary w-48 mb-1 email_data_btn"
on:click={() => {
if (!confirm(`Are you sure you want to send this email? To: ${$ae_loc.user_email}?`)) {return false;}
@@ -504,7 +560,47 @@ function send_guest_list_email() {
>
<span class="fas fa-paper-plane mx-1"></span>
Email With Guest List
</button> -->
<button
class="btn btn-sm variant-ghost-warning w-42 mb-1 generate_csv_btn text-xs"
on:click={() => {
if (!confirm('Generate and download a CSV file with the guest list?')) {
return false;
}
let csv_data = generate_guest_list_csv($slct.sponsorship_obj_li);
console.log('CSV Data:', csv_data);
}}
>
<span class="fas fa-file-csv mx-1"></span>
Export Guest List CSV
</button>
<span id="download_csv_container"></span>
<button
on:click={async () => {
console.log('Show hidden sponsorships');
if ($ae_loc.qry__hidden == 'all') {
$ae_loc.qry__hidden = 'not_hidden';
$slct_trigger = 'load__sponsorship_obj_li';
} else {
$ae_loc.qry__hidden = 'all';
$slct_trigger = 'load__sponsorship_obj_li';
}
}}
class="btn btn-sm variant-ghost-warning w-42 mb-1 text-xs"
>
{#if $ae_loc.qry__hidden == 'all'}
<span class="fas fa-eye mx-1"></span>
Hide Hidden Sponsorships
{:else}
<span class="fas fa-eye-slash mx-1"></span>
Show Hidden Sponsorships
{/if}
</button>
</span>
{/if}
</section>

View File

@@ -2527,19 +2527,43 @@ async function handle_delete_sponsorship_obj({sponsorship_id, hosted_file_id=nul
{#if $slct.sponsorship_id}
<!-- {#if $ae_loc.trusted_access} -->
<span class="ae_actions">
{#if $ae_loc.administrator_access}
<button
on:click={() => {
if (!confirm('CURRENTLY DISABLED: Are you sure you want to delete this sponsorship?')) {return false;}
// handle_delete_sponsorship_obj({sponsorship_id: $slct.sponsorship_id, method: 'delete'});
if (!confirm('Are you sure you want to delete this sponsorship?')) {return false;}
// $slct.sponsorship_id = null;
// $slct.sponsorship_obj = {};
handle_delete_sponsorship_obj({sponsorship_id: $slct.sponsorship_id, method: 'delete'});
$slct.sponsorship_id = null;
$slct.sponsorship_obj = {};
}}
class="btn btn-sm variant-glass-warning mx-1"
title="Delete record permanently"
>
<span class="fas fa-minus mx-1"></span> Delete
</button>
{/if}
<button
on:click={() => {
if (!confirm('Are you sure you want to remove this sponsorship?')) {return false;}
let method = 'hide';
if ($ae_loc.trusted_access) {
method = 'disable';
} else {
method = 'hide';
}
handle_delete_sponsorship_obj({sponsorship_id: $slct.sponsorship_id, method: method});
$slct.sponsorship_id = null;
$slct.sponsorship_obj = {};
}}
class="btn btn-sm variant-glass-warning mx-1"
class:hidden={!$ae_loc.administrator_access}
title="CURRENTLY DISABLED: Delete record permanently"
title="Remove sponsorship"
>
<span class="fas fa-minus mx-1"></span> Delete
<span class="fas fa-trash mx-1"></span> Remove
</button>
<button

View File

@@ -41,6 +41,7 @@ onMount(() => {
<tr
id={`ae_sponsorship_id__${ae_sponsorship_obj.sponsorship_id_random}`}
class="ae_object sponsorship_obj"
class:fade_50={ae_sponsorship_obj.hide}
>
<td class="ae_options sponsorship_obj__options">