449 Commits

Author SHA1 Message Date
Scott Idem
c212eeb45e Initial testing with Svelte version 3. 2024-10-14 15:53:29 -04:00
Scott Idem
115751bcd7 Code updates for IDAA migration 2024-10-14 14:25:29 -04:00
Scott Idem
ca2658a324 Just package updates. Nothing should have broken... 2024-10-11 17:09:31 -04:00
Scott Idem
338c9b9b23 Making things look nicer still. 2024-10-10 16:44:23 -04:00
Scott Idem
5037579abe Cleaning things up. Making it easier to find things. 2024-10-10 16:02:47 -04:00
Scott Idem
980e8850be More clean up. 2024-10-10 13:14:38 -04:00
Scott Idem
ec2c37b715 Cleaned up the code. A lot less _random!! 2024-10-10 13:13:21 -04:00
Scott Idem
9093cc9957 Renamed some things to remove the _random part. 2024-10-10 12:56:22 -04:00
Scott Idem
79bc148e85 We can now download files remotely! 2024-10-09 20:47:46 -04:00
Scott Idem
6694ec92c7 Renamed a bunch of functions! 2024-10-08 16:34:06 -04:00
Scott Idem
c130e82fd0 Minor code clean up 2024-10-08 16:24:06 -04:00
Scott Idem
bd48596176 Better loading of presentations, presenters, and files. 2024-10-08 16:22:38 -04:00
Scott Idem
816db5281d Small permission view change 2024-10-08 15:03:06 -04:00
Scott Idem
d5ac26f0ef Use a list of file purpose options per event. 2024-10-08 14:38:39 -04:00
Scott Idem
f9b3b3a0eb Minor change 2024-10-08 14:10:43 -04:00
Scott Idem
a6b9115865 Working on handling received messages. Open a session. 2024-10-08 12:13:27 -04:00
Scott Idem
0799f9a1ab Show and hide the main launcher menu 2024-10-07 18:47:41 -04:00
Scott Idem
c3f4832f48 Now with a better download file container thing. Can change open with OS. 2024-10-07 18:30:09 -04:00
Scott Idem
03e6117024 Work on being remotely controlled. 2024-10-07 15:58:56 -04:00
Scott Idem
ccb36ca953 Cleaning things up like always. 2024-10-07 15:29:20 -04:00
Scott Idem
2ac495af8e Cleaned up the show/hide location and launcher links. 2024-10-07 14:47:26 -04:00
Scott Idem
820c151750 First attempt to add Google Analytics to SvelteKit. This should be per site. 2024-10-07 14:19:32 -04:00
Scott Idem
aef469ad9d Wrapping up for the day. Lots of tedious work on the Launcher. 2024-10-04 18:23:47 -04:00
Scott Idem
b6cd3f59e5 Work on the dev env and building for production and staging. 2024-10-03 20:48:41 -04:00
Scott Idem
7b84e1c1fc More work on the site permissions. 2024-10-03 16:29:45 -04:00
Scott Idem
0f49afec12 Working on improved default permissions and allow control per site and site domains. 2024-10-03 16:04:00 -04:00
Scott Idem
d6d4c88728 Various changes... Should have saved last night. Also send_email should NOT default to test mode! 2024-10-03 12:45:28 -04:00
Scott Idem
bb27942b52 Enable more security by default. 2024-10-02 18:21:01 -04:00
Scott Idem
89dd410aeb API bug fixes. Clean up. New util functions. Highlight times for newer files. 2024-10-02 17:32:36 -04:00
Scott Idem
1004104de0 Not sure... 2024-10-02 13:55:33 -04:00
Scott Idem
0e7df79bab Trying to fix things... 2024-10-02 13:33:17 -04:00
Scott Idem
581749ff41 The IDAA Recovery Meetings view and edit now display mostly correct. They still need work though. 2024-10-02 13:13:23 -04:00
Scott Idem
a189a1c336 Now the enable and hide buttons work. 2024-10-01 18:47:08 -04:00
Scott Idem
1c1845280b The search is working better now. Also better and less debug logging. 2024-10-01 18:09:27 -04:00
Scott Idem
fad58bf26f More general clean up. Making event queries easier to use and understand. 2024-10-01 16:59:08 -04:00
Scott Idem
47e9f9f5a1 General clean up. Improved event search and listing for IDAA. 2024-10-01 16:08:31 -04:00
Scott Idem
cca43b957a The event search now mostly works. 2024-10-01 13:36:50 -04:00
Scott Idem
d7284d5010 Improvement and updates to the event list loading and showing. 2024-10-01 11:28:50 -04:00
Scott Idem
35c901f144 Started pulling in the IDAA Bulletin Board code 2024-09-27 18:55:24 -04:00
Scott Idem
58928d07eb Moving files around 2024-09-27 17:42:46 -04:00
Scott Idem
6a8148228f Organizing things better. Hopefully nothing is broken!! Still need to move the event session related. 2024-09-27 17:21:57 -04:00
Scott Idem
d6c26e7511 The initial migration for IDAA Recovery Meetings. Progress 2024-09-27 15:20:26 -04:00
Scott Idem
495dd0e6d9 Trying to make the slightly newer event session search page load consistently. 2024-09-27 13:08:31 -04:00
Scott Idem
25a28d4ff6 Moved the AE Utilities functions 2024-09-27 10:46:28 -04:00
Scott Idem
894c84b857 Revert back to older Session Search page. 2024-09-26 19:12:46 -04:00
Scott Idem
8b6f171506 Cleaned up links. Added links in the Launcher to go back to the session search, location view, and session view. 2024-09-26 19:00:32 -04:00
Scott Idem
5311e4704f Work on the Launcher and how a "group" presenter is shown. 2024-09-26 18:37:09 -04:00
Scott Idem
0f40629bfe Done with clean up for the night. Still need to rename all of the shared functions that start with handle_. 2024-09-25 19:09:28 -04:00
Scott Idem
702da83ce5 Clean up before I wrap up for the day. 2024-09-25 18:54:45 -04:00
Scott Idem
32ca117b11 More work to prepare the new Archives, Posts, and Recovery Meetings 2024-09-25 18:44:49 -04:00
Scott Idem
283850e917 Adding in the Archives and Posts DB and functions to get ready for IDAA changes. 2024-09-25 17:55:42 -04:00
Scott Idem
514f36d998 Update to show the timestamps for bio updates. 2024-09-25 14:47:07 -04:00
Scott Idem
cc4446b549 More updates related to permissions. 2024-09-25 13:21:28 -04:00
Scott Idem
8005189bc4 Quick update for LCI 2024-09-25 12:54:58 -04:00
Scott Idem
41706fbcd7 Moving things around and preping things for IDAA. Archive, Posts, Recovery Meetings 2024-09-24 20:05:52 -04:00
Scott Idem
6dc89083ec Starting to import the IDAA files. 2024-09-24 18:32:19 -04:00
Scott Idem
267b5052c9 Moving more files around. 2024-09-24 18:23:22 -04:00
Scott Idem
9e6a7f0db0 Making the Launcher reload when link clicked to go there. 2024-09-24 17:15:06 -04:00
Scott Idem
476b303da4 Lots of work on the new Launcher. Also general reorganizing of files. 2024-09-24 16:55:23 -04:00
Scott Idem
bd2583fde3 Better scaling as the width changes 2024-09-23 16:42:53 -04:00
Scott Idem
80b394f16b Better sorting for files 2024-09-23 15:29:23 -04:00
Scott Idem
36283a215b Related bug fixes and updates for remote limits 2024-09-23 15:01:14 -04:00
Scott Idem
a92f8a486e Fixed the sorting of the files 2024-09-23 14:46:20 -04:00
Scott Idem
f9e156e862 Worked on new message for session page view. Wrapping up for the day. 2024-09-18 19:07:18 -04:00
Scott Idem
37c40ff4fc Changed the version number. Just because. 2024-09-18 18:16:14 -04:00
Scott Idem
2cf1ea39a8 Updated wording for default label. 2024-09-18 18:12:51 -04:00
Scott Idem
63f17e111b Improved the flexibility of the event files upload component. 2024-09-18 17:52:28 -04:00
Scott Idem
e46fa59a40 Require higher permission to edit 2024-09-18 17:07:27 -04:00
Scott Idem
ce476f9a65 Improvement in the showing of the edit button. 2024-09-18 17:03:49 -04:00
Scott Idem
04b549b874 I should have committed this earlier. Lots of changes to use LiveQuery and better menus. 2024-09-18 16:45:49 -04:00
Scott Idem
fd152cc27e Work on making wrappers and code clean up 2024-09-18 12:16:36 -04:00
Scott Idem
86b309f048 Making wrappers for some of the elements that will be expecting LQ variables directly. 2024-09-18 11:36:59 -04:00
Scott Idem
04fd046c53 Trying to get everything using the newer session list. Also trying to generally pass the LQ values directly to the child component. 2024-09-17 19:15:43 -04:00
Scott Idem
e95191d43a More package updates. Things seem to be working... 2024-09-17 17:28:21 -04:00
Scott Idem
3b56223be3 Package updates 2024-09-17 17:20:48 -04:00
Scott Idem
77b14a387e General clean up. Also changed everything over to data store element version 2. Seems to be working well... 2024-09-17 17:17:20 -04:00
Scott Idem
527d1f82b7 Now using the new new new, not mine, Modal element. 2024-09-16 19:02:16 -04:00
Scott Idem
1e3086560d Creating version to of the data store element. Hopefully better now. 2024-09-16 18:10:55 -04:00
Scott Idem
9fd84183d7 Renaming the page access code to site access code. 2024-09-16 16:25:53 -04:00
Scott Idem
f9c3fe4b21 Broad clean up of code. 2024-09-16 16:15:14 -04:00
Scott Idem
d122d1fb93 Trying to clean up things so they load faster. 2024-09-16 15:41:06 -04:00
Scott Idem
c7b48ca97a Chasing and fixing bugs 2024-09-16 15:09:23 -04:00
Scott Idem
1faf7fb18f Adding more options related to session content. 2024-09-16 14:43:28 -04:00
Scott Idem
3a6c462155 Changing the datetime formatter a bit. 2024-09-16 12:20:28 -04:00
Scott Idem
2a3e386f6f Always trying to keep things consistent. 2024-09-13 17:22:21 -04:00
Scott Idem
c711b29bea Making the buttons look the same... 2024-09-13 17:12:19 -04:00
Scott Idem
be58d87faf The session agreements look good. Time to clean up the presenter agreements to match. 2024-09-13 16:51:17 -04:00
Scott Idem
59eed57dec Now with updated_on date times. Other improvements and clean up. 2024-09-13 16:20:56 -04:00
Scott Idem
3d34e30c63 Added the opt out options to the session POC agree page. 2024-09-13 15:40:02 -04:00
Scott Idem
896fb76cc6 More work on the agreements and separating things into files. 2024-09-13 15:05:44 -04:00
Scott Idem
7e610ead67 Work on the new session POC functions and permissions. General code clean up and bug fixes. 2024-09-13 13:20:04 -04:00
Scott Idem
e7e532f61a Improvements to bio and agree 2024-09-12 19:36:33 -04:00
Scott Idem
9fd9f61ddb Bug fix for fields not set yet. 2024-09-12 18:52:59 -04:00
Scott Idem
e3b808a0e0 A lot of work to get the LCI Champions able to add a biography and agree to Terms and Conditions. 2024-09-12 18:37:03 -04:00
Scott Idem
225dd678a5 Minor updates 2024-09-12 14:06:22 -04:00
Scott Idem
0ae86593cd Text updates 2024-09-12 13:25:03 -04:00
Scott Idem
792c496d46 Setting a new version for this app 2024-09-12 13:16:40 -04:00
Scott Idem
faf37f8159 New branch and updates to the workspace file 2024-09-12 13:09:12 -04:00
Scott Idem
5b8121bfc7 Starting new branch and updating packages 2024-09-12 13:03:51 -04:00
Scott Idem
32f24f8ffa Minor update to style 2024-09-09 00:07:25 -04:00
Scott Idem
eacd40ac21 Clean up of the launcher links still... 2024-09-09 00:04:59 -04:00
Scott Idem
bf5bdd4a3e Work on the links to the legacy and new launchers. 2024-09-08 23:28:34 -04:00
Scott Idem
5fcae3b047 Sort of fix for the agreement text (LCI buttons) not showing correctly. 2024-09-06 18:50:44 -04:00
Scott Idem
8b913b73f8 Working on adjusting the permissions for session POC. They can upload/download files for the session and each presenter. 2024-09-04 16:06:50 -04:00
Scott Idem
86dc7797e0 Minor changes related to the site passcodes. 2024-09-04 15:19:45 -04:00
Scott Idem
d5d28149ad More work on making things look better. File counts look nicer. 2024-09-04 14:41:02 -04:00
Scott Idem
917cca09ce Cleaning up the hide/unhide buttons 2024-09-04 13:31:47 -04:00
Scott Idem
3919347383 General clean up and standardizing of things. More option buttons. Show/hide from launcher. 2024-09-04 13:05:21 -04:00
Scott Idem
5aaaaa164d Now with search by location name! 2024-09-03 17:42:15 -04:00
Scott Idem
e6694718e7 Work on location links and fixing presenters not showing correctly on session view page. 2024-09-03 16:41:54 -04:00
Scott Idem
9a0112e884 Work on location views and editing. Also session list clean up. 2024-09-03 14:51:36 -04:00
Scott Idem
acf89f3fa5 Style clean up 2024-08-23 18:35:27 -04:00
Scott Idem
4881fcf7f2 Hide the event files button for now. 2024-08-23 16:39:23 -04:00
Scott Idem
4fa8d0368f Working on the styling some more. 2024-08-23 16:34:28 -04:00
Scott Idem
014d244019 Merge remote-tracking branch 'refs/remotes/origin/ae_app_template_dev' into ae_app_template_dev 2024-08-23 14:35:17 -04:00
Scott Idem
4dbdd16bd0 Recovering from something that broke the styling. It is not 100% right, but much better. 2024-08-23 14:26:17 -04:00
Scott Idem
45d7cba562 General clean up. Trying to make things load faster and more smoothly. 2024-08-21 18:55:12 -04:00
Scott Idem
fed37a77b8 Working on sign in checking and permissions. This probably still needs to be reviewed some more. 2024-08-21 15:34:34 -04:00
Scott Idem
d8edd658b0 Adding a new notes module I guess. Because why not. 2024-08-20 21:00:03 -04:00
Scott Idem
5139a706d0 Removing hardcoded LCI related. General clean up of things. 2024-08-20 12:59:35 -04:00
Scott Idem
608bef7f21 Wrapping up for the day 2024-08-19 18:06:36 -04:00
Scott Idem
c61d3a4dca Trying to make this LiveQuery work. 2024-08-19 17:56:32 -04:00
Scott Idem
4871464adf Minor clean up 2024-08-19 16:45:11 -04:00
Scott Idem
722acdaa59 Apparently not much with badge printing... Cleaned up some code. 2024-08-19 16:30:27 -04:00
Scott Idem
1d496eb769 Duplicated and modified how the event file manager works slightly. 2024-08-19 15:23:34 -04:00
Scott Idem
75b0e53114 General clean up and renaming of functions. 2024-08-19 14:53:28 -04:00
Scott Idem
6aa499c79b Package updates 2024-08-19 14:34:40 -04:00
Scott Idem
fefd7c8027 Dim hidden sessions and presenters in the list 2024-08-19 14:24:10 -04:00
Scott Idem
85138e7b44 Wrapping up for the day. It is Friday. Things mostly work. 2024-08-16 18:34:54 -04:00
Scott Idem
68727d24cf Hide the Copy Access Link button if no person ID linked 2024-08-16 18:02:34 -04:00
Scott Idem
fa55e96be2 Refresh files after upload. For now this clears everything. It is may not be the most efficient, but it works. 2024-08-16 17:41:34 -04:00
Scott Idem
b0e15700b5 Adding config options and toggles for various things. 2024-08-16 17:18:15 -04:00
Scott Idem
37801ca769 Fixes for the reports. General clean up all around. Better usage of log_lvl. 2024-08-16 13:14:18 -04:00
Scott Idem
ca563fdf1f Merge remote-tracking branch 'refs/remotes/origin/ae_app_template_dev' into ae_app_template_dev
Merging changes from yesterday. Thought I did this already.
2024-08-16 10:06:47 -04:00
Scott Idem
fed5d2de65 Clean up based on notes. Adding some JSON event config options for presenter agree and presenter bio. 2024-08-16 10:06:16 -04:00
Scott Idem
f58cd9611b Config change 2024-08-15 21:29:37 -04:00
Scott Idem
7d167444c4 Cleaned up the presenter view. Less fields show if the person is not linked. 2024-08-15 20:18:09 -04:00
Scott Idem
5208480614 Made the session menu look nicer. 2024-08-15 19:52:12 -04:00
Scott Idem
f674503b21 Fixes for the QR codes refreshing too easily. Added option to turn the QR codes off and on. Need to add an event level setting or something. 2024-08-15 18:51:16 -04:00
Scott Idem
002c283c68 Working on dealing with the QR codes re-generating too easily. 2024-08-15 18:04:14 -04:00
Scott Idem
46cc89ad92 Bug fixes for the bio field and copy button 2024-08-15 16:34:34 -04:00
Scott Idem
f209f3ce37 Bug fix for biography copy button 2024-08-15 16:14:01 -04:00
Scott Idem
ef62b30dc9 Now with copy button for presenter bio 2024-08-15 15:49:26 -04:00
Scott Idem
fdca94b625 Minor updates to access 2024-08-15 15:42:18 -04:00
Scott Idem
f526e9094c Various bug fixes. Improvements to the security. Now with super and manager and others. 2024-08-15 15:35:00 -04:00
Scott Idem
35052898b4 Clean up. New ability to save the session search text. 2024-08-15 14:14:41 -04:00
Scott Idem
146bea0a67 Staring work on getting Electron working from Svelte app. Wrapping up for the day. 2024-08-14 19:23:29 -04:00
Scott Idem
cc4588c8a6 Renaming more of the standard object functions. 2024-08-14 16:16:56 -04:00
Scott Idem
0ec9cbbd08 Renaming standard object functions 2024-08-14 16:06:21 -04:00
Scott Idem
be81122e4e General clean up 2024-08-14 15:57:57 -04:00
Scott Idem
56c16bef10 Minor changes 2024-08-14 14:37:53 -04:00
Scott Idem
380a8d2ad3 Allow trusted access to new report 2024-08-14 14:07:21 -04:00
Scott Idem
0d48362529 Work on CRUD v2 API calls. Added sessions without files report. 2024-08-14 14:05:48 -04:00
Scott Idem
efedc88ade Minor fix for help buttons and button styling 2024-08-14 09:39:35 -04:00
Scott Idem
ca2dc11206 Done for the night. 2024-08-13 21:40:14 -04:00
Scott Idem
bdfb276199 Now with better reports showing and status. 2024-08-13 21:36:01 -04:00
Scott Idem
06a1d7a771 Cleaning things up. Minor bug fixes. 2024-08-13 20:57:19 -04:00
Scott Idem
53fea0d25d Cleaned up the menus. Added new options for max qry limits. 2024-08-13 20:01:44 -04:00
Scott Idem
37b2145f81 Now with ability to toggle hidden and disabled sessions. 2024-08-13 18:58:56 -04:00
Scott Idem
e83623526c Minor clean up 2024-08-13 16:52:38 -04:00
Scott Idem
3639342356 Minor bug fix and clean up 2024-08-13 16:48:35 -04:00
Scott Idem
00fcd8e747 Added ability to upload files individually to get the % uploaded. Added show/hide of manage files for sessions and presenters. Other clean up. 2024-08-13 16:42:10 -04:00
Scott Idem
d5dbeeabf7 Maybe wrapping up for the day. 2024-08-12 18:41:33 -04:00
Scott Idem
df36727540 Working on a better file upload element and component. Slow progress... 2024-08-12 18:35:36 -04:00
Scott Idem
074cf154f2 Improvement with file counts and related 2024-08-09 19:33:47 -04:00
Scott Idem
d7dfef4fe0 Wrapping up for the day/week. It is my birthday weekend! 2024-08-09 19:01:45 -04:00
Scott Idem
9a1995dd9f Lots of changes. Things are working better. Files are now showing for the session and presenter. Next is location and event. 2024-08-09 17:50:54 -04:00
Scott Idem
30e6384772 I quite for the night! The presentation list shows now... 2024-08-08 20:42:04 -04:00
Scott Idem
14fc1ee146 Now I am trying to get the presentation list to display... Why won't this work...? Adding URL params seems to have helped some. 2024-08-08 19:51:03 -04:00
Scott Idem
4ddc775aaa Things are finally working better again with the liveQuery. I hope. 2024-08-08 16:55:50 -04:00
Scott Idem
4141524d83 Just saving things... Not making good progress today. 2024-08-08 15:48:49 -04:00
Scott Idem
f407565fc7 Fixed up the new Launcher. The Dexie liveQuery is now working better. Added await tick();. 2024-08-07 18:37:45 -04:00
Scott Idem
cb1f4343db Show star for priority presenter 2024-08-07 17:32:05 -04:00
Scott Idem
ccd91571ce Bug fixes for sign in and related 2024-08-07 17:21:10 -04:00
Scott Idem
75ee8e1b5c Working on bug fix for sign in vs the selected presentation and presenter. Partially fixed. 2024-08-07 16:09:17 -04:00
Scott Idem
7aebf24996 Should have saved my work earlier... General clean up of initial API calls and saving to IDB. Other fixes and updates. 2024-08-07 15:26:58 -04:00
Scott Idem
0d34f81fa7 Wrapping up for the day. The new launcher is partially working. There is a lot of work to do. 2024-08-02 19:11:35 -04:00
Scott Idem
352639e702 Pulled out the event reports page menu. And other clean up. 2024-08-02 12:05:00 -04:00
Scott Idem
8d7627fd36 Clean up of button text 2024-08-01 21:08:45 -04:00
Scott Idem
40293e25b4 Making things scale better 2024-08-01 20:42:28 -04:00
Scott Idem
bf31a3f596 Minor menu show/hide fix 2024-08-01 20:01:34 -04:00
Scott Idem
ff498ed49e Fixed spacing... 2024-08-01 19:55:26 -04:00
Scott Idem
2177f6c379 Now with the event session search menu separated out. Also other clean up. 2024-08-01 19:52:52 -04:00
Scott Idem
98d09bac76 The session and presenter headers both look good. 2024-08-01 18:56:28 -04:00
Scott Idem
e0e380e450 Bug fixes and small improvements. The session page menu is now separate. Still testing that out. 2024-08-01 17:21:59 -04:00
Scott Idem
e7b7948b06 Going live with the new menu after some testing. 2024-08-01 16:33:03 -04:00
Scott Idem
cf9f914412 The new menu for the session page is working well. Time for clean up. 2024-08-01 15:43:39 -04:00
Scott Idem
2fca5b2c3b Creating new session_view.svelte. General clean up related to that and presenter_view.svelte 2024-08-01 10:46:09 -04:00
Scott Idem
f8b53baee8 Making things look nicer. 2024-07-25 18:26:38 -04:00
Scott Idem
86c8aa6c83 Now with hide files from launcher working. event_file.hide 2024-07-25 18:20:17 -04:00
Scott Idem
4a70869896 Improving person reports and related 2024-07-25 13:25:25 -04:00
Scott Idem
0ca8da1a6e Bug fix for total file count for a session 2024-07-25 12:51:34 -04:00
Scott Idem
d756059ad4 Now with ability to clear IDB event_file list 2024-07-25 12:36:39 -04:00
Scott Idem
6b9284951e General improvements to reports 2024-07-25 11:29:59 -04:00
Scott Idem
8b53cd2b7f End user should not see the person link 2024-07-24 18:33:21 -04:00
Scott Idem
fdb435cd1e Got rid of dollar symbol 2024-07-24 18:27:45 -04:00
Scott Idem
37c51cee29 Now with JSON validity checking. Done for the day. 2024-07-24 18:22:19 -04:00
Scott Idem
274b599ff1 Now with new button toggles and edit for JSON data! 2024-07-24 18:06:10 -04:00
Scott Idem
98849427d9 Scroll bars only show when needed in Chrome now. "auto" instead of "scroll" 2024-07-24 15:05:25 -04:00
Scott Idem
027d7a781d General clean up related to permissions and updating fields. 2024-07-24 15:00:48 -04:00
Scott Idem
c41be23995 Package updates and related 2024-07-23 18:40:15 -04:00
Scott Idem
b0633a5c24 Bug fixes for the file rename. 2024-07-19 17:01:42 -04:00
Scott Idem
b2293784e0 Now with the ability to rename files. Had to add a new Dexie update IDB function. 2024-07-19 16:40:56 -04:00
Scott Idem
af17a05022 Now with QR codes for sessions and presenters! 2024-07-18 17:15:12 -04:00
Scott Idem
a6f8f00e9e Implementing bug fix for Svelte params not being ready under my data value. Loading and referencing the params directly/explicitly instead. 2024-07-18 10:09:56 -04:00
Scott Idem
070e714aff Bug fix for loading pages with params! I think this has been a root cause of some of the issues for a while now. 2024-07-18 09:21:29 -04:00
Scott Idem
43488b8f76 Wrapping up for the day. I need to research this. Why does the first link (anchor tag) that is hovered over (triggers pre-load) fail if the URL has a “slug” value? Or any URL??? Any links after the first seem to pre-load fine. 2024-07-17 18:30:08 -04:00
Scott Idem
d16c47fedf Testing preloading 2024-07-17 18:24:43 -04:00
Scott Idem
064bba3d62 Reports can set max count. Bug fixes. Clean up. 2024-07-17 17:08:09 -04:00
Scott Idem
625169a321 Work on new core person list, view, and edit 2024-07-17 14:59:15 -04:00
Scott Idem
ad1e42010a Show more results by default 2024-07-12 16:24:47 -04:00
Scott Idem
997f470ebe Now with a new recent files report. 2024-07-12 16:20:23 -04:00
Scott Idem
47c742d004 Wrapping up for the day. The first report looks pretty good. 2024-07-11 17:44:43 -04:00
Scott Idem
945c943c61 Added a reports section and the first report. Agreed presenters. 2024-07-11 17:01:44 -04:00
Scott Idem
7eb3080f46 Updating packages. Stuck with issues related to ESLint and TypeScript. A version conflict. 2024-07-11 13:52:48 -04:00
Scott Idem
1bf90f128f Updates for the browser title. Wrapping up for the day! July 4th week! 2024-07-03 18:48:28 -04:00
Scott Idem
8f2eb2c27e Forgot to lock some fields down. And other minor changes. 2024-07-03 18:23:59 -04:00
Scott Idem
4aae2bead4 Separating out components and functions to make things more modular. 2024-07-03 17:48:06 -04:00
Scott Idem
270a1429f8 None code change 2024-07-03 11:54:31 -04:00
Scott Idem
a2d3d5b1f7 NPM package updates 2024-07-03 11:45:30 -04:00
Scott Idem
26a0a1dbd6 Working on new inline components for presenter list and event file list. 2024-07-02 18:53:41 -04:00
Scott Idem
889500e80d Finally got the horizontal scroll working correctly with the table. 2024-07-02 18:17:38 -04:00
Scott Idem
d8e062b8c7 Work in progress of moving the session list out to a separate component. 2024-07-02 15:42:45 -04:00
Scott Idem
a1515ba6b6 Code clean up 2024-07-02 14:35:12 -04:00
Scott Idem
27bed2f532 At good point for session searching. 2024-07-02 14:19:04 -04:00
Scott Idem
f4006e7226 The rate limited and delayed search is now working. 2024-07-02 14:00:39 -04:00
Scott Idem
afbe396caf Cleaning up search 2024-07-02 11:54:07 -04:00
Scott Idem
aae19249d4 More efficient query results processing 2024-07-02 11:38:33 -04:00
Scott Idem
d410953ce4 Work on new LiveQuery search results 2024-07-02 09:42:52 -04:00
Scott Idem
40aba339f8 Work on LiveQuery 2024-07-02 09:33:16 -04:00
Scott Idem
ed89c61aed Slight change to header padding 2024-07-01 23:30:43 -04:00
Scott Idem
6d06347e0a Will come back to the LiveQuery undefined thing later... 2024-07-01 20:37:19 -04:00
Scott Idem
acc39ecb50 Wrapping up for the day. Trying to get LQ to work with searching and bulkGet. 2024-07-01 20:33:57 -04:00
Scott Idem
861107c2fd Ready to move on to other areas. 2024-07-01 17:01:48 -04:00
Scott Idem
245757b501 Working on the logic for permissions 2024-07-01 16:53:54 -04:00
Scott Idem
88b0042919 This should have been saved earlier. Lots of moving code around to and clean up. 2024-07-01 16:22:10 -04:00
Scott Idem
9de9d31101 Trying to fix scrolling of the table. 2024-06-28 23:24:29 -04:00
Scott Idem
acaff7634d A lot of code clean up. Also making things look better. 2024-06-28 17:56:39 -04:00
Scott Idem
9f7a19c4b9 Making things look nicer 2024-06-28 13:06:13 -04:00
Scott Idem
e6aec67247 Minor changes 2024-06-28 12:17:43 -04:00
Scott Idem
4183c9022c Now with presenter biography. Used the speakers collection that was done for CHOW as the basis. 2024-06-28 12:02:45 -04:00
Scott Idem
298f87960a Now with ability to sync person record to presenter record. Also some other editing. 2024-06-28 10:45:37 -04:00
Scott Idem
a0085723c9 Now with new file manager 2024-06-28 09:48:12 -04:00
Scott Idem
d01ab2479f Ready to swap out the temporary presenter view file manager section 2024-06-28 09:42:51 -04:00
Scott Idem
2d490d8058 Fixed presentation name edit permissions 2024-06-27 18:43:01 -04:00
Scott Idem
a34d2af18e Show full SHA hash in title 2024-06-27 18:24:25 -04:00
Scott Idem
12c778c7e2 Now with a better file manager. It still needs work. 2024-06-27 18:19:29 -04:00
Scott Idem
37ac30c56c Working on new standalone event file manage element 2024-06-27 15:51:49 -04:00
Scott Idem
8c8748b571 Making more fields us the LiveQuery. Migrated format bytes function. General clean up. 2024-06-27 10:57:19 -04:00
Scott Idem
20e1c46461 Making things look better. Now with a person look up for the presenter record. Wrapping up for the day. 2024-06-26 18:19:17 -04:00
Scott Idem
4d7e48a170 Making things look pretty 2024-06-26 14:39:30 -04:00
Scott Idem
dd9c48e801 Minor fixes and new warning for outdated "app" version. 2024-06-26 14:06:38 -04:00
Scott Idem
7faa9d0459 Work on help information for session search and session view 2024-06-26 11:38:20 -04:00
Scott Idem
6a22f84f23 Failed to switch to LiveQuery for presenter list 2024-06-25 19:07:38 -04:00
Scott Idem
b604eaee56 Saving before trying to use live query with presentation list 2024-06-25 18:10:14 -04:00
Scott Idem
68d376b88d Now able to do stuff with the locations 2024-06-25 18:06:56 -04:00
Scott Idem
0090058238 Just working on select option list and related. 2024-06-25 14:50:40 -04:00
Scott Idem
a62ea7dc8d Making things work better. Adding CRUD select option list. 2024-06-25 14:05:03 -04:00
Scott Idem
21ad9d900c Adding the ability to quickly edit most fields. Other general clean up. 2024-06-25 11:37:03 -04:00
Scott Idem
4ad51b8e0b Wrapping up for the day. Now with ability to add a person. 2024-06-24 19:45:15 -04:00
Scott Idem
384f91bbe7 Create presentations and presenters. Making things look nicer. 2024-06-24 19:09:40 -04:00
Scott Idem
58a975bfe9 Updating npm and Svelte 2024-06-24 16:04:44 -04:00
Scott Idem
c6b7c7e803 Better (less) logging and other clean up 2024-06-24 15:51:30 -04:00
Scott Idem
0c4185f74c General code clean up 2024-06-24 14:42:14 -04:00
Scott Idem
31ba1c9200 Split up the giant events functions file! 2024-06-24 14:32:25 -04:00
Scott Idem
5211f83f23 Now with file counts on the search results! Done for the day. 2024-06-21 16:57:43 -04:00
Scott Idem
ecf2b3eca8 Now with updated POC edit and other 2024-06-21 16:03:08 -04:00
Scott Idem
e5cff89acb Now with search on presenter's name and email 2024-06-21 15:08:58 -04:00
Scott Idem
87b4f22bb1 Added select no POC option 2024-06-21 12:29:32 -04:00
Scott Idem
2552e1a839 Now with upload and download percent! Also better editing for session POC. 2024-06-21 12:25:36 -04:00
Scott Idem
fd114bce22 Now with the ability to edit a presentation name. Yay. 2024-06-20 18:32:24 -04:00
Scott Idem
991cb1e9da Working on ability to change the presentation name and session name... Making progress. Need to figure out why the file list does not reload correctly right after saving. 2024-06-20 17:45:00 -04:00
Scott Idem
d49f73583c Now with clear search text button. 2024-06-20 13:47:40 -04:00
Scott Idem
8c52722408 Bug fixes and clean up of Dexie DB related 2024-06-19 16:27:16 -04:00
Scott Idem
06add80718 A lot of cosmetic clean up and some code clean up. Also new util functions from old Svelte NPM library. 2024-06-19 14:01:15 -04:00
Scott Idem
5ef2d05e9c Enable emailing sign in links 2024-06-18 18:49:30 -04:00
Scott Idem
baf354fd46 Minor text change 2024-06-18 15:53:20 -04:00
Scott Idem
8044cd0723 POC sign is mostly working now 2024-06-18 15:52:14 -04:00
Scott Idem
519525540c File uploads for event presenters works. Other minor clean up. 2024-06-14 16:38:15 -04:00
Scott Idem
97f15f41f7 Finally got the presenter file upload working better. 2024-06-14 16:23:10 -04:00
Scott Idem
06df9a6230 Everything is working except for the file uploads 2024-06-14 14:42:49 -04:00
Scott Idem
65daf86cc7 General clean up of things 2024-06-14 11:23:37 -04:00
Scott Idem
37547a96d8 Time for bed! 2024-06-14 00:39:38 -04:00
Scott Idem
0156426f4b Trying to get things ready for tomorrow. Now with saving of opt outs and other. 2024-06-14 00:34:24 -04:00
Scott Idem
58d25e922c Stopping for dinner and a break. 2024-06-13 19:08:09 -04:00
Scott Idem
6bcc554737 Clean up of auth logic 2024-06-13 15:42:30 -04:00
Scott Idem
84f6f1eda8 Trying to wrap up for the day. 2024-06-12 18:58:06 -04:00
Scott Idem
b368abc91a Almost ready for LCI demo... 2024-06-12 13:23:56 -04:00
Scott Idem
987e411956 Now with session searching working 2024-06-12 13:00:27 -04:00
Scott Idem
bbd403b96d More updates 2024-06-11 20:02:37 -04:00
Scott Idem
98cd149d2c Lots of work on things for LCI! Should have saved more often. 2024-06-11 19:31:44 -04:00
Scott Idem
7cd71299b3 Changes for CHOW deadline 2024-06-07 11:47:28 -04:00
Scott Idem
87ef4cc6b9 Better update to the results cap based on admin or trusted 2024-05-29 15:09:31 -04:00
Scott Idem
8b201a68ed Increased list cap 2024-05-29 15:05:33 -04:00
Scott Idem
359c147167 Moving things to SK. Added events and sessions. 2024-05-24 19:02:52 -04:00
Scott Idem
d9ff625db6 More code clean up 2024-05-23 19:45:17 -04:00
Scott Idem
0005ba7dc9 Code clean up 2024-05-23 18:59:50 -04:00
Scott Idem
42fef3feb8 Re-working the API library functions and files 2024-05-23 18:20:31 -04:00
Scott Idem
fa58d1accb Changes from before AAPOR 2024-05-20 17:24:23 -04:00
Scott Idem
f72d7be5b2 Work on general clean up. Better export and email of sponsor data 2024-05-03 17:07:08 -04:00
Scott Idem
a3a32e188d Should have saved earlier... 2024-04-25 16:11:18 -04:00
Scott Idem
94d0cfeb4d Working on better bug fix for downloading export files. Some columns were missing. 2024-04-23 18:52:41 -04:00
Scott Idem
69c1250961 Improved downloading export files. 2024-04-23 17:42:44 -04:00
Scott Idem
2aff1aadbe Export now works for Sponsors, Speakers, and Leads 2024-04-23 17:10:24 -04:00
Scott Idem
ca04e9739f Saving my work! 2024-04-23 16:36:08 -04:00
Scott Idem
38e73cb40c Adding back in the sponsorship export stuff I was working on... Annoyed. 2024-04-23 15:53:43 -04:00
a87b4d53a0 Unknown changes from last week in Prague? 2024-04-23 15:37:51 -04:00
f8e81bf7e4 Better style 2024-04-11 11:32:45 -04:00
d242948d7e Show or hide alert. Enable or disable the default to scan 2024-04-11 11:17:59 -04:00
21ee101007 Clean up of style 2024-04-11 10:40:23 -04:00
2b61b8f4a5 Style updates 2024-04-11 10:11:44 -04:00
ab268532da Padding change and minor layout change 2024-04-11 06:27:46 -04:00
920dd176fe I am done for the night/morning... 2024-04-10 20:31:32 -04:00
5411df5893 Trying things... 2024-04-10 04:45:48 -04:00
ab906e4af1 More comments 2024-04-10 00:16:08 -04:00
46dcd389a4 This is nearly working. 2024-04-10 00:14:53 -04:00
f405d1b3b7 Quick save of things 2024-04-10 00:09:57 -04:00
0aae7f9361 I don't know 2024-04-09 23:35:19 -04:00
a51e96ea6e Hopefully this works... QR stop and start? 2024-04-09 23:05:32 -04:00
f68bccddb9 Trying to make things work for the morning... 2024-04-09 21:25:12 -04:00
4460b38098 Style clean up 2024-04-09 06:34:34 -04:00
8e6ab2c223 More generic short_name for PWA 2024-04-09 04:30:22 -04:00
d64a20e5b3 Done for the night for real! 2024-04-08 20:27:17 -04:00
f5ab1cecc1 Done for the night. 2024-04-08 20:11:47 -04:00
ef583e1328 Getting the badge search really ready 2024-04-08 19:12:44 -04:00
9eee2a928b Now supports the new redirect to the new search 2024-04-08 13:15:39 -04:00
1ae1a3d989 The AND LIKE query is now working! 2024-04-07 17:26:48 -04:00
bde3229270 Working on making the LIKE query work correctly. 2024-04-07 14:06:31 -04:00
02af46a48f The leads should be ready to go now..... 2024-04-07 12:59:06 -04:00
Scott Idem
562479313d Hiding not ready warning messages 2024-04-05 11:39:11 -04:00
Scott Idem
a5b0720933 More fixes 2024-04-04 23:39:18 -04:00
Scott Idem
847fad3151 Last minute updates 2024-04-04 23:31:59 -04:00
Scott Idem
16f65cf85f Now with much better badge search function. And bug fix for Payment tab. 2024-04-04 21:33:45 -04:00
Scott Idem
5671423467 Getting the badges up and running again 2024-04-03 19:37:28 -04:00
Scott Idem
8d2f4e30f4 Almost everything works!! Need to clean up export file. Missing custom questions and similar. 2024-04-03 18:10:47 -04:00
Scott Idem
9c85914b9f Progress 2024-04-03 16:28:11 -04:00
Scott Idem
ae1764579e Making things look good and fewer bugs 2024-04-03 15:54:51 -04:00
Scott Idem
b5588fd9a1 Slow and steady progress getting things working more smoothly. 2024-04-03 14:54:33 -04:00
Scott Idem
1555f0f8d0 Fixes for saving custom leads questions and adding by badge ID 2024-04-03 11:22:38 -04:00
Scott Idem
3abe92a2dc Various bug fixes for CHOW 2024-04-01 20:48:16 -04:00
Scott Idem
78b5fc1068 I am done...? 2024-03-29 20:33:10 -04:00
Scott Idem
841367afeb Changes have been made... 2024-03-29 15:35:40 -04:00
Scott Idem
0e26765312 General clean up. Less debug. Things work better? 2024-03-29 12:15:50 -04:00
Scott Idem
c0e1d666f4 Minor 2024-03-28 19:31:09 -04:00
Scott Idem
7a4a4cab5e Now with auto hide header and footer 2024-03-28 19:16:07 -04:00
Scott Idem
741878172c Less logging 2024-03-28 19:01:26 -04:00
Scott Idem
2b1b2b7d07 Now with ability to email license sign in link 2024-03-28 18:55:31 -04:00
Scott Idem
9851c69c30 Making things work smoothly 2024-03-28 17:34:19 -04:00
Scott Idem
86972f5a02 Svelte framework and lib updates 2024-03-28 13:23:58 -04:00
Scott Idem
b7bf152366 General updates 2024-03-28 12:58:23 -04:00
Scott Idem
7cc23077f3 Done for the night I guess. 2024-03-27 20:15:30 -04:00
Scott Idem
b336f18512 Testing auto reloading data stores. 2024-03-27 19:21:57 -04:00
Scott Idem
378ae11224 I think things are mostly working now... 2024-03-27 19:21:39 -04:00
Scott Idem
8d8fb0b638 I guess this is better than it was... 2024-03-27 17:55:31 -04:00
Scott Idem
3082c07e3e Should have saved my progress earlier. Trying to redo things without using localStorage initially. Shared data... 2024-03-27 11:36:06 -04:00
Scott Idem
a8a2131361 I am not really sure... I just want it to load correctly. 2024-03-26 20:15:24 -04:00
Scott Idem
a30690ea2a Mostly working before major fix for data shared. 2024-03-26 18:25:43 -04:00
Scott Idem
f20c6ef706 Finally getting the initial loading better 2024-03-26 17:12:35 -04:00
Scott Idem
4d486a580c Trying to make things work better... 2024-03-26 14:24:35 -04:00
Scott Idem
040e1e71e3 One last little bug 2024-03-25 20:25:15 -04:00
Scott Idem
54fb837581 Bug fix for QR scan. Clean up for the day! 2024-03-25 20:15:02 -04:00
Scott Idem
3ddef770c0 General work through out the day. Lots of interruptions from the dogs. 2024-03-25 19:26:49 -04:00
Scott Idem
b0f2e2ccdf Done for the day 2024-03-22 19:16:14 -04:00
Scott Idem
f97c83db03 Quick save before trying more drastic options for sorting and filtering... 2024-03-22 14:07:07 -04:00
Scott Idem
742205b84b Done for the night! 2024-03-21 20:02:17 -04:00
Scott Idem
976f4fe8c0 Done for the night 2024-03-21 19:45:42 -04:00
Scott Idem
cd79213b37 Wrapping up for the day? 2024-03-21 18:29:12 -04:00
Scott Idem
18c1c84044 This is a good point for things. Looks good and working well. 2024-03-21 18:13:05 -04:00
Scott Idem
7381797a28 This is just a good clean point of development. Still a lot of work though! 2024-03-21 15:20:48 -04:00
Scott Idem
c490bca265 Stuck and done for the night 2024-03-20 19:39:48 -04:00
Scott Idem
e21b7ef584 General clean up and making things a least look real. 2024-03-20 16:33:36 -04:00
Scott Idem
84e3098b72 Lots of general clean up and fixes. 2024-03-20 13:31:42 -04:00
Scott Idem
fbbaa1392b Wrapping up for the day. Lots of changes. 2024-03-19 20:23:42 -04:00
Scott Idem
19d2dd630b Minor fixes. Passes the client-reference-id to Stripe 2024-03-19 13:10:46 -04:00
Scott Idem
e4687aab2f Finalish updates before sending emails to ISHLT exhibitors 2024-03-19 11:38:47 -04:00
Scott Idem
d3ae087cd6 Lots of updates.... 2024-03-18 21:36:03 -04:00
Scott Idem
9b02b2f86c Bug fix for exhibit_id missing. Why? 2024-03-15 18:46:34 -04:00
Scott Idem
7d86a9b40f Wrapping up for the day? Now with iframe sort of support 2024-03-15 18:02:12 -04:00
Scott Idem
0400aa429b It has been a long two or three weeks... 2024-03-15 17:48:14 -04:00
Scott Idem
68b0efb6c9 Now with QR code scanner! 2024-03-14 20:31:37 -04:00
Scott Idem
20b42ac6aa Things are working! 2024-03-14 19:43:54 -04:00
Scott Idem
a97e5666a7 Just working on things. Slow progress... 2024-03-14 18:11:09 -04:00
Scott Idem
8bf1892bc7 Working on adding/updating licenses 2024-03-13 19:53:10 -04:00
Scott Idem
3f664eb5c0 Saving my work and trying something a little different. Using a number as the id instead of the email address. I feel like this will also cause issues. 2024-03-13 18:06:22 -04:00
Scott Idem
3c30664b2b Last minute work for CHOW. Hopefully done soon... 2024-03-13 10:32:22 -04:00
Scott Idem
fd4f2bdf35 Finally working Events - Leads for exhibitors 2024-03-12 19:28:10 -04:00
Scott Idem
7d1a4b735b Making things look nicer and more complete. 2024-03-12 14:29:16 -04:00
Scott Idem
a5431070d3 Minor changes 2024-03-11 14:06:53 -04:00
Scott Idem
ef2597d114 Bug fixes and clean up for CHOW 2024-03-11 12:48:23 -04:00
Scott Idem
1559bae11c General checks and clean up of things 2024-03-10 16:01:53 -04:00
Scott Idem
b6ba167a86 Done for the night! 2024-03-08 21:17:07 -05:00
Scott Idem
4136c08cdb Sponsor Hub part looks pretty good now. Still need to enable the delete buttons. 2024-03-08 21:09:58 -05:00
Scott Idem
875f327c90 Speakers form is now working pretty well. Including delete. 2024-03-08 18:00:36 -05:00
Scott Idem
b53566aa41 Minor changes 2024-03-08 14:41:36 -05:00
Scott Idem
d9ee195590 Documentation for what reason? 2024-03-08 13:08:54 -05:00
Scott Idem
409872ed4d More changes 2024-03-08 11:43:32 -05:00
Scott Idem
2ada1419d8 Lots of general clean up and work for CHOW going live 2024-03-08 11:27:18 -05:00
Scott Idem
5a147a98bb I am done for the night... 2024-03-08 00:09:17 -05:00
Scott Idem
1694dfb5c5 Getting ready to implement Dexie for Svelte 2024-03-07 13:33:51 -05:00
Scott Idem
ff00ec5c91 Ready to demo for Precon CHOW again 2024-03-07 12:09:23 -05:00
Scott Idem
c6abc0abca Clean up for CHOW... 2024-03-07 11:28:30 -05:00
Scott Idem
b020ded01c Changes. Work on new review page searching. 2024-03-06 20:39:38 -05:00
Scott Idem
aa712284ce Just worki on things 2024-03-06 13:47:41 -05:00
Scott Idem
e71cdab353 Wrapping up for the night. Things are working better. There are still API request misses or something. 2024-03-05 20:35:38 -05:00
Scott Idem
bed4f4a0f2 Work on the new Data Store element 2024-03-05 17:01:37 -05:00
Scott Idem
19a6ff6dbe Work on expanding the routes 2024-03-04 20:55:48 -05:00
Scott Idem
6c60ee3086 More quick updates and clean up 2024-03-04 13:43:24 -05:00
Scott Idem
a0947e349a General clean up for CHOW. 2024-03-04 10:59:15 -05:00
Scott Idem
04a8b49177 Quick changes for CHOW 2024-03-04 08:46:12 -05:00
Scott Idem
63990bb36a More changes based on feedback 2024-03-03 19:52:42 -05:00
Scott Idem
60f6386415 Changes based on feedback from Jordan (and Erin) 2024-03-03 19:22:44 -05:00
Scott Idem
7051cb92d5 Event presenter now has a slug directory 2024-03-03 12:51:14 -05:00
Scott Idem
64589ec11c Too many changes. Getting ready to show Jordan. 2024-03-03 12:31:32 -05:00
Scott Idem
1b12cd4aec Lots of bug fixes. Lots of clean up. Things work more consitently. 2024-03-02 20:54:45 -05:00
Scott Idem
4db9e68543 A lot of little changes everywhere. Sorry... 2024-03-02 20:09:25 -05:00
Scott Idem
0dbf869d5d Work on file related 2024-03-02 11:28:13 -05:00
Scott Idem
e69ff969f5 Walking away 2024-03-01 19:15:22 -05:00
Scott Idem
ff90fa5287 Done for reals... 2024-03-01 19:10:26 -05:00
Scott Idem
f09577d1d5 Done for the night... 2024-03-01 19:02:05 -05:00
Scott Idem
9fe4c51a67 Wrapping up for Friday night 2024-03-01 18:55:26 -05:00
Scott Idem
f4ed04497e Style clean up. A lot! Almost ready for CHOW going live. 2024-03-01 16:17:02 -05:00
Scott Idem
b21f9c0437 Wrapping up for the night. Mostly good for demo tomorrow morning. 2024-02-29 20:24:08 -05:00
Scott Idem
873e6d9f9a General clean up. Presenter form submission now works better. Need to do the same for the sponsorships submission form. 2024-02-29 16:14:31 -05:00
Scott Idem
e713313aca Bug fix for null bio field 2024-02-29 14:49:24 -05:00
Scott Idem
addadacc47 Getting ready for CHOW 2024 demo call tomorrow 2024-02-29 14:37:37 -05:00
Scott Idem
9310aac4d2 Button fix 2024-02-28 21:47:57 -05:00
Scott Idem
2c7e7ca027 Will now pull in agreements and accommations questions 2024-02-28 21:17:09 -05:00
Scott Idem
713fcb3c62 Bug fixes. Style setting improvements. 2024-02-28 15:45:02 -05:00
Scott Idem
00a28588b7 Wrapping up for the day 2024-02-27 20:21:02 -05:00
Scott Idem
ed97cba7a6 General clean up of code. Starting to wrap up for the night. 2024-02-27 19:20:21 -05:00
Scott Idem
714642380e Cleaning up code and making everything look better. 2024-02-27 18:38:46 -05:00
Scott Idem
22efa3fd96 Made the closing of the modals cleaner 2024-02-27 17:04:03 -05:00
Scott Idem
c93d84f3c3 Sponsorships and Speakers are working and looking pretty well. Other general clean up. 2024-02-27 16:50:37 -05:00
Scott Idem
9540aefd50 Finally got things working. Store act odd when being set under layout.ts? 2024-02-26 21:04:17 -05:00
Scott Idem
060c0500d3 General clean up. No working on the new event presenter components. 2024-02-26 15:03:01 -05:00
Scott Idem
740baa689e Need to work on not havnig the account ID set 2024-02-22 22:16:49 -05:00
Scott Idem
02f693c13e Making the loading a bit more efficient and cleaner 2024-02-22 20:28:29 -05:00
Scott Idem
d1328eb67c Added the access code component. Improved layout. General clean up and improvements. 2024-02-22 17:21:22 -05:00
Scott Idem
5a13852432 Wrapping up programming for tonight. Ready for CHOW demo? 2024-02-20 19:07:09 -05:00
Scott Idem
d51d059535 Finally got things mostly working. 2024-02-20 18:05:18 -05:00
Scott Idem
5bb9134641 I need to stop for the night. 2024-02-19 19:37:03 -05:00
Scott Idem
3403210efd This is the first commit of the day. It is probably the last. Lots of general prep for a demo. 2024-02-19 18:28:55 -05:00
Scott Idem
6f0680f282 Good first draft. Done for the night! 2024-02-16 22:15:54 -05:00
Scott Idem
bab68af7dc Making progress on pulling this together. 2024-02-16 21:38:41 -05:00
Scott Idem
9958724aaa I should have saved this long ago. Lots of changes. Learning a lot as well! 2024-02-16 20:12:19 -05:00
Scott Idem
cb9bd1648c Done for the night! 2024-02-15 19:19:01 -05:00
Scott Idem
a3d4354ef4 This is a good start. Many key features are working again!!! 2024-02-15 18:53:26 -05:00
Scott Idem
19f9983c9a Most things are working in the template now. 2024-02-15 11:55:42 -05:00
Scott Idem
17d99d080c Starting a new template using Svelte, SvelteKit, Tailwind, and Skeleton. 2024-02-15 09:49:35 -05:00
939 changed files with 71438 additions and 4872 deletions

View File

@@ -1,5 +1,5 @@
[Dolphin]
Timestamp=2024,2,6,18,10,21.847
Timestamp=2024,8,7,10,25,9.632
Version=4
ViewMode=1

43
.env.prod.default Normal file
View File

@@ -0,0 +1,43 @@
# One Sky IT's Aether Framework and System
TESTING=This is a test env variable
PUBLIC_TESTING=This is a public test env variable
CONTAINER_AE_APP_NODE=ae_app_node_prod
CONTAINER_AE_APP_NODE_RED=ae_app_node_prod_red
CONTAINER_AE_APP_NODE_GREEN=ae_app_node_prod_green
CONTAINER_AE_APP_NODE_BLUE=ae_app_node_prod_blue
OSIT_WEB_HTTP_PORT=8082
OSIT_WEB_HTTPS_PORT=4435
# DOCKER_AE_SERVER_EXTRA_HOST=srv-nyx.oneskyit.com:104.237.143.4
# DOCKER_AE_API_SERVER_EXTRA_HOST=api.oneskyit.com:104.237.143.4
# DOCKER_AE_API_BAK_SERVER_EXTRA_HOST=bak-api.oneskyit.com:104.237.143.4
# Aether general shared config options
# For general shared config options like API access and use, database access and use, Redis, and SMTP
# home development, live testing, live production, onsite development, onsite testing, onsite production???
AE_CFG_ID=7
## Aether API access and use
PUBLIC_AE_API_PROTOCOL=https
PUBLIC_AE_API_SERVER=api.oneskyit.com
PUBLIC_AE_API_BAK_SERVER=bak-api.oneskyit.com
PUBLIC_AE_API_SERVER_INTERNAL=aether_api_gunicorn
PUBLIC_AE_API_PORT=443
PUBLIC_AE_API_PATH=
PUBLIC_AE_API_SECRET_KEY=XXXX
PUBLIC_AE_API_CRUD_SUPER_KEY=XXXX
PUBLIC_AE_NO_ACCOUNT_ID=No_Account_ID_Here
PUBLIC_AE_NO_ACCOUNT_ID_TOKEN=Nothing_to_see_here
# Aether app specific config (SvelteKit)
AE_APP_CFG_ID=99
AE_APP_ENV=development
AE_APP_NODE_PORT=3001
AE_APP_NODE_PORT_RED=3002
AE_APP_NODE_PORT_GREEN=3003
AE_APP_NODE_PORT_BLUE=3004
PUBLIC_AE_ACCOUNT_ID=XXXX # OSIT = _XY7DXtc9MY; CHOW = 3Iid1aIRY5j
PUBLIC_AE_EVENT_ID=XXXX # OSIT = pjrcghqwert; CHOW = Mw6-Nv-Zf-5A
PUBLIC_AE_SPONSORSHIP_CFG_ID=XXXX # OSIT = t8jdjONCs0k; CHOW = ygjEuQQCzvk

45
.env.staging.default Normal file
View File

@@ -0,0 +1,45 @@
# One Sky IT's Aether Framework and System
TESTING=This is a test env variable
PUBLIC_TESTING=This is a public test env variable
CONTAINER_AE_APP_NODE=ae_app_node_prod
CONTAINER_AE_APP_NODE_RED=ae_app_node_prod_red
CONTAINER_AE_APP_NODE_GREEN=ae_app_node_prod_green
CONTAINER_AE_APP_NODE_BLUE=ae_app_node_prod_blue
OSIT_WEB_HTTP_PORT=8082
OSIT_WEB_HTTPS_PORT=4435
# DOCKER_AE_SERVER_EXTRA_HOST=srv-nyx.oneskyit.com:104.237.143.4
# DOCKER_AE_API_SERVER_EXTRA_HOST=dev-api.oneskyit.com:192.168.32.20 # Odd because this env is the development server
# DOCKER_AE_API_SERVER_EXTRA_HOST=dev-api.oneskyit.com:192.168.32.99 # Odd because this env is the development server
# DOCKER_AE_API_BAK_SERVER_EXTRA_HOST=test-api.oneskyit.com:104.237.143.4 # Odd because this env is the development server
# DOCKER_AE_API_TEST_SERVER_EXTRA_HOST=test-api.oneskyit.com:104.237.143.4
# Aether general shared config options
# For general shared config options like API access and use, database access and use, Redis, and SMTP
# home development, live testing, live production, onsite development, onsite testing, onsite production???
AE_CFG_ID=5
## Aether API access and use
PUBLIC_AE_API_PROTOCOL=https
PUBLIC_AE_API_SERVER=dev-api.oneskyit.com
PUBLIC_AE_API_BAK_SERVER=test-api.oneskyit.com
PUBLIC_AE_API_SERVER_INTERNAL=aether_api_gunicorn
PUBLIC_AE_API_PORT=443
PUBLIC_AE_API_PATH=
PUBLIC_AE_API_SECRET_KEY=dFP6J9DVj9hUgIMn-fNIqg
PUBLIC_AE_API_CRUD_SUPER_KEY=zp5PtX4zUsI
PUBLIC_AE_NO_ACCOUNT_ID=No_Account_ID_Here
PUBLIC_AE_NO_ACCOUNT_ID_TOKEN=Nothing_to_see_here
# Aether app specific config (SvelteKit)
AE_APP_CFG_ID=99
AE_APP_ENV=development
AE_APP_NODE_PORT=3001
AE_APP_NODE_PORT_RED=3002
AE_APP_NODE_PORT_GREEN=3003
AE_APP_NODE_PORT_BLUE=3004
PUBLIC_AE_ACCOUNT_ID=XXXX # OSIT = _XY7DXtc9MY; CHOW = 3Iid1aIRY5j
PUBLIC_AE_EVENT_ID=XXXX # OSIT = pjrcghqwert; CHOW = Mw6-Nv-Zf-5A
PUBLIC_AE_SPONSORSHIP_CFG_ID=XXXX # OSIT = t8jdjONCs0k; CHOW = ygjEuQQCzvk

13
.eslintignore Normal file
View File

@@ -0,0 +1,13 @@
.DS_Store
node_modules
/build
/.svelte-kit
/package
.env
.env.*
!.env.example
# Ignore files for PNPM, NPM and YARN
pnpm-lock.yaml
package-lock.json
yarn.lock

31
.eslintrc.cjs Normal file
View File

@@ -0,0 +1,31 @@
/** @type { import("eslint").Linter.Config } */
module.exports = {
root: true,
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:svelte/recommended',
'prettier'
],
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint'],
parserOptions: {
sourceType: 'module',
ecmaVersion: 2020,
extraFileExtensions: ['.svelte']
},
env: {
browser: true,
es2017: true,
node: true
},
overrides: [
{
files: ['*.svelte'],
parser: 'svelte-eslint-parser',
parserOptions: {
parser: '@typescript-eslint/parser'
}
}
]
};

37
.gitignore vendored
View File

@@ -1,27 +1,32 @@
.DS_Store
node_modules
/build
/.svelte-kit
/package
.env
.env.*
!.env.example
!.env.prod.default
!.env.staging.default
vite.config.js.timestamp-*
vite.config.ts.timestamp-*
# Logs
logs
*.log
*.log.*
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
# Backups and archives
*.bak
*.tar.gz
backups/
# Temporary files
tmp/
temp/
*.kate-swp

1
.npmrc Normal file
View File

@@ -0,0 +1 @@
engine-strict=true

4
.prettierignore Normal file
View File

@@ -0,0 +1,4 @@
# Ignore files for PNPM, NPM and YARN
pnpm-lock.yaml
package-lock.json
yarn.lock

8
.prettierrc Normal file
View File

@@ -0,0 +1,8 @@
{
"useTabs": true,
"singleQuote": true,
"trailingComma": "none",
"printWidth": 100,
"plugins": ["prettier-plugin-svelte"],
"overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }]
}

View File

@@ -1,3 +0,0 @@
{
"recommendations": ["svelte.svelte-vscode"]
}

120
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,120 @@
{
"prettier.documentSelectors": [
"**/*.svelte"
],
"tailwindCSS.classAttributes": [
"class",
"accent",
"active",
"animIndeterminate",
"aspectRatio",
"background",
"badge",
"bgBackdrop",
"bgDark",
"bgDrawer",
"bgLight",
"blur",
"border",
"button",
"buttonAction",
"buttonBack",
"buttonClasses",
"buttonComplete",
"buttonDismiss",
"buttonNeutral",
"buttonNext",
"buttonPositive",
"buttonTextCancel",
"buttonTextConfirm",
"buttonTextFirst",
"buttonTextLast",
"buttonTextNext",
"buttonTextPrevious",
"buttonTextSubmit",
"caretClosed",
"caretOpen",
"chips",
"color",
"controlSeparator",
"controlVariant",
"cursor",
"display",
"element",
"fill",
"fillDark",
"fillLight",
"flex",
"flexDirection",
"gap",
"gridColumns",
"height",
"hover",
"inactive",
"indent",
"justify",
"meter",
"padding",
"position",
"regionAnchor",
"regionBackdrop",
"regionBody",
"regionCaption",
"regionCaret",
"regionCell",
"regionChildren",
"regionChipList",
"regionChipWrapper",
"regionCone",
"regionContent",
"regionControl",
"regionDefault",
"regionDrawer",
"regionFoot",
"regionFootCell",
"regionFooter",
"regionHead",
"regionHeadCell",
"regionHeader",
"regionIcon",
"regionInput",
"regionInterface",
"regionInterfaceText",
"regionLabel",
"regionLead",
"regionLegend",
"regionList",
"regionListItem",
"regionNavigation",
"regionPage",
"regionPanel",
"regionRowHeadline",
"regionRowMain",
"regionSummary",
"regionSymbol",
"regionTab",
"regionTrail",
"ring",
"rounded",
"select",
"shadow",
"slotDefault",
"slotFooter",
"slotHeader",
"slotLead",
"slotMessage",
"slotMeta",
"slotPageContent",
"slotPageFooter",
"slotPageHeader",
"slotSidebarLeft",
"slotSidebarRight",
"slotTrail",
"spacing",
"text",
"track",
"transition",
"width",
"zIndex"
]
}

148
README.md
View File

@@ -1,2 +1,146 @@
# OSIT AE - Sponsorships App (Svelte)
This was created for One Sky IT's Aether system.
# One Sky IT's Aether App - SvelteKit v2
This uses SvelteKit version 2, TailwindCSS, and Skelton.
# Current Modules
## AE Events - Speakers (/events_speakers)
### Components
* +page.svelte - The main page for the Events - Speakers module
* 10_edit_modal__event_presenter_obj.svelte - The modal for editing a presenter
* 10_list__event_presenter_obj.svelte - The list of presenters/speakers
* 10_view_modal__event_presenter_obj.svelte - The modal for viewing a presenter
#### [slug]
* +page.svelte - The main page for the presenter ID [slug]
## AE Sponsorships (/sponsorships)
* +page.svelte - The main page for the Sponsorships module
* 10_edit_modal__sponsorship_obj.svelte - The modal for editing a sponsorship
* 10_list__sponsorship_obj.svelte - The list of sponsorships
* 10_view_modal__sponsorship_obj.svelte - The modal for viewing a sponsorship
#### [slug]
* +page.svelte - The main page for the sponsorship ID [slug]
# Future Modules
## AE Events - Badges (/events_badges)
* +page.svelte - The main page for the Events - Badges module
* 10_list__event_badge_obj.svelte - The list of badges
* 10_view_modal__event_badge_obj.svelte - The modal for viewing a badge
## AE Events - Exhibit Leads (/events_exhibit_leads)
## AE Events - Presentation Management (/events_pres_mgmt)
# How to build and deploy SvelteKit:
Copy the contents of the "build" directory to ./npm_deploy/build/
```bash
npm run build
```
If this is just a quick build update then only the build directory needs to be copied (rsync).
```bash
rsync -vhrz --exclude 'node_modules' ~/OSIT_dev/ae_app_svelte_tailwind_skeleton/build/ ~/OSIT_dev/ae_env_node_app/npm_deploy/build/ --delete
rsync -vhrz ~/OSIT_dev/ae_env_node_app/npm_deploy/build/ scott@linode.oneskyit.com:/srv/env/prod_aether_sveltekit/npm_deploy/build/ --delete
```
If this includes package updates we need to copy the new package.json. Manually copy the new package.json file to ./npm_deploy/. This also needs to be copied to the server.
```bash
# copy/paste, rsync, or cp
```
Run the --omit dev to clear out the node_modules directory. Copy the root node_modules directory to ./npm_deploy/build/node_modules/ after running te omit dev command.
```bash
npm ci --omit dev
```
Everything should be ready to run on the development server and production server.
# Rebuild the node_modules directory and manually install extra Svelte packages
Run the npm update to fix the node_modules directory and package.json
```bash
npm update
```
Other installs?:
Are both still needed? I know at least one of these is. 2024-07-23
```bash
npm install --save-dev svelte-highlight
npm install --save-dev typescript-svelte-plugin
```
# Set up and run
## Packages and dependencies
```bash
npm install --save-dev svelte-highlight typescript-svelte-plugin
npm install flowbite flowbite-svelte tailwind-merge @popperjs/core
```
## Build
## Environment file
### ".env"
This is the default used if others are not found when when "npm run dev" or "npm run build" is run.
### ".env.local"
This is used when "npm run dev" is run. This is not used in the production build.
### ".env.production"
This is used when "npm run build" is run. This is not used in the development build.
### ".env:prod"
This is modified to allow for a staging environment and production environment built.
### ".env:staging"
This is modified to allow for a staging environment and production environment built.
### Example Important Values when running in dev:
Note our home IP address that changes.
```bash
DOCKER_AE_API_SERVER_EXTRA_HOST=dev-api.oneskyit.com:108.28.68.107
PUBLIC_AE_API_SERVER=api.oneskyit.com
PUBLIC_AE_API_BAK_SERVER=bak-api.oneskyit.com
```
# create-svelte
Everything you need to build a Svelte project, powered by [`create-svelte`](https://github.com/sveltejs/kit/tree/main/packages/create-svelte).
## Creating a project
If you're seeing this, you've probably already done this step. Congrats!
```bash
# create a new project in the current directory
npm create svelte@latest
# create a new project in my-app
npm create svelte@latest my-app
```
## Developing
Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
```bash
npm run dev
# or start the server and open the app in a new browser tab
npm run dev -- --open
```
## Building
To create a production version of your app:
```bash
npm run build
```
You can preview the production build with `npm run preview`.
> To deploy your app, you may need to install an [adapter](https://kit.svelte.dev/docs/adapters) for your target environment.

View File

@@ -1,8 +0,0 @@
{
"folders": [
{
"path": "."
}
],
"settings": {}
}

View File

@@ -0,0 +1,14 @@
{
"folders": [
{
"path": "."
}
],
"settings": {
"cSpell.words": [
"filelist"
],
"git.autofetch": true,
"editor.defaultFormatter": "svelte.svelte-vscode"
}
}

View File

@@ -1,49 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<!-- Load dayjs library: https://cdnjs.com/libraries/dayjs -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/dayjs/1.11.10/dayjs.min.js" integrity="sha512-FwNWaxyfy2XlEINoSnZh1JQ5TRRtGow0D6XcmAWmYCRgvqOUTnzCxPc9uF35u5ZEpirk1uhlPVA19tflhvnW1g==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dayjs/1.11.10/plugin/utc.min.js" integrity="sha512-z84O912dDT9nKqvpBnl1tri5IN0j/OEgMzLN1GlkpKLMscs5ZHVu+G2CYtA6dkS0YnOGi3cODt3BOPnYc8Agjg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dayjs/1.11.10/plugin/timezone.min.js" integrity="sha512-jmsGNYDezdyZ+W3bVeZy83kZp/2n5BgWe/0solkveG0vSSrP9XIVTD1tNiM1OqImc4H3OxHfs1uSfVclOU3mWw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://static.oneskyit.com/js/tinymce/tinymce.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" integrity="sha512-1ycn6IcaQQ40/MKBW2W4Rhis/DbILU74C1vSrLJxCq57o941Ym01SwNsOMqvEBFlcgUa6xLiPY/NS5R+E6ztJQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<!-- <link rel="stylesheet" href="/src/main.css" /> -->
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>&AElig; AE App (The Hub) - Sponsorships - Vite + Svelte + TS</title>
<script>
let api_base_url = 'https://dev-api.oneskyit.com';
let api_base_url_backup = 'https://bak-api.oneskyit.com';
let app_base_url = 'https://dev-demo.oneskyit.com';
let app_base_url_backup = 'https://bak-demo.oneskyit.com';
</script>
<script>
</script>
</head>
<body>
<section id="Site-Header">Site-Header</section>
<section id="Site-Nav-Menu"></section>
<!-- <section id="Notifications">Notifications</section> -->
<div class="svelte_target ae_svelte_app ae_sponsorships_main"></div>
<section id="Site-Set-Access-Type" class="svelte_target set_access_type"></section>
<section id="Site-Footer">Site-Footer</section>
<section id="Site-Modals"><!-- Site-Modals --></section>
<div class="svelte_target ae_svelte_app_hub"></div>
<!-- The ae_bridge_init.js and main.ts should be run back to back -->
<script src="/ae_bridge_init.js"></script>
<script type="module" src="/src/main.ts"></script>
</body>
</html>

103
osit_ae_theme_1.ts Normal file
View File

@@ -0,0 +1,103 @@
import type { CustomThemeConfig } from '@skeletonlabs/tw-plugin';
export const myCustomTheme: CustomThemeConfig = {
name: 'my-custom-theme',
properties: {
// =~= Theme Properties =~=
"--theme-font-family-base": `Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'`,
"--theme-font-family-heading": `Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'`,
"--theme-font-color-base": "0 0 0",
"--theme-font-color-dark": "255 255 255",
"--theme-rounded-base": "16px",
"--theme-rounded-container": "8px",
"--theme-border-base": "1px",
// =~= Theme On-X Colors =~=
"--on-primary": "0 0 0",
"--on-secondary": "0 0 0",
"--on-tertiary": "0 0 0",
"--on-success": "0 0 0",
"--on-warning": "0 0 0",
"--on-error": "0 0 0",
"--on-surface": "0 0 0",
// =~= Theme Colors =~=
// primary | #99c1f1
"--color-primary-50": "240 246 253", // #f0f6fd
"--color-primary-100": "235 243 252", // #ebf3fc
"--color-primary-200": "230 240 252", // #e6f0fc
"--color-primary-300": "214 230 249", // #d6e6f9
"--color-primary-400": "184 212 245", // #b8d4f5
"--color-primary-500": "153 193 241", // #99c1f1
"--color-primary-600": "138 174 217", // #8aaed9
"--color-primary-700": "115 145 181", // #7391b5
"--color-primary-800": "92 116 145", // #5c7491
"--color-primary-900": "75 95 118", // #4b5f76
// secondary | #8ff0a4
"--color-secondary-50": "238 253 241", // #eefdf1
"--color-secondary-100": "233 252 237", // #e9fced
"--color-secondary-200": "227 251 232", // #e3fbe8
"--color-secondary-300": "210 249 219", // #d2f9db
"--color-secondary-400": "177 245 191", // #b1f5bf
"--color-secondary-500": "143 240 164", // #8ff0a4
"--color-secondary-600": "129 216 148", // #81d894
"--color-secondary-700": "107 180 123", // #6bb47b
"--color-secondary-800": "86 144 98", // #569062
"--color-secondary-900": "70 118 80", // #467650
// tertiary | #f8e45c
"--color-tertiary-50": "254 251 231", // #fefbe7
"--color-tertiary-100": "254 250 222", // #fefade
"--color-tertiary-200": "253 248 214", // #fdf8d6
"--color-tertiary-300": "252 244 190", // #fcf4be
"--color-tertiary-400": "250 236 141", // #faec8d
"--color-tertiary-500": "248 228 92", // #f8e45c
"--color-tertiary-600": "223 205 83", // #dfcd53
"--color-tertiary-700": "186 171 69", // #baab45
"--color-tertiary-800": "149 137 55", // #958937
"--color-tertiary-900": "122 112 45", // #7a702d
// success | #33d17a
"--color-success-50": "224 248 235", // #e0f8eb
"--color-success-100": "214 246 228", // #d6f6e4
"--color-success-200": "204 244 222", // #ccf4de
"--color-success-300": "173 237 202", // #adedca
"--color-success-400": "112 223 162", // #70dfa2
"--color-success-500": "51 209 122", // #33d17a
"--color-success-600": "46 188 110", // #2ebc6e
"--color-success-700": "38 157 92", // #269d5c
"--color-success-800": "31 125 73", // #1f7d49
"--color-success-900": "25 102 60", // #19663c
// warning | #ffa348
"--color-warning-50": "255 241 228", // #fff1e4
"--color-warning-100": "255 237 218", // #ffedda
"--color-warning-200": "255 232 209", // #ffe8d1
"--color-warning-300": "255 218 182", // #ffdab6
"--color-warning-400": "255 191 127", // #ffbf7f
"--color-warning-500": "255 163 72", // #ffa348
"--color-warning-600": "230 147 65", // #e69341
"--color-warning-700": "191 122 54", // #bf7a36
"--color-warning-800": "153 98 43", // #99622b
"--color-warning-900": "125 80 35", // #7d5023
// error | #f66151
"--color-error-50": "254 231 229", // #fee7e5
"--color-error-100": "253 223 220", // #fddfdc
"--color-error-200": "253 216 212", // #fdd8d4
"--color-error-300": "251 192 185", // #fbc0b9
"--color-error-400": "249 144 133", // #f99085
"--color-error-500": "246 97 81", // #f66151
"--color-error-600": "221 87 73", // #dd5749
"--color-error-700": "185 73 61", // #b9493d
"--color-error-800": "148 58 49", // #943a31
"--color-error-900": "121 48 40", // #793028
// surface | #deddda
"--color-surface-50": "250 250 249", // #fafaf9
"--color-surface-100": "248 248 248", // #f8f8f8
"--color-surface-200": "247 247 246", // #f7f7f6
"--color-surface-300": "242 241 240", // #f2f1f0
"--color-surface-400": "232 231 229", // #e8e7e5
"--color-surface-500": "222 221 218", // #deddda
"--color-surface-600": "200 199 196", // #c8c7c4
"--color-surface-700": "167 166 164", // #a7a6a4
"--color-surface-800": "133 133 131", // #858583
"--color-surface-900": "109 108 107", // #6d6c6b
}
}

103
osit_ae_theme_2.ts Normal file
View File

@@ -0,0 +1,103 @@
import type { CustomThemeConfig } from '@skeletonlabs/tw-plugin';
export const myCustomTheme: CustomThemeConfig = {
name: 'my-custom-theme',
properties: {
// =~= Theme Properties =~=
"--theme-font-family-base": `Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'`,
"--theme-font-family-heading": `Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'`,
"--theme-font-color-base": "0 0 0",
"--theme-font-color-dark": "255 255 255",
"--theme-rounded-base": "16px",
"--theme-rounded-container": "8px",
"--theme-border-base": "1px",
// =~= Theme On-X Colors =~=
"--on-primary": "0 0 0",
"--on-secondary": "0 0 0",
"--on-tertiary": "0 0 0",
"--on-success": "0 0 0",
"--on-warning": "0 0 0",
"--on-error": "0 0 0",
"--on-surface": "0 0 0",
// =~= Theme Colors =~=
// primary | #62a0ea
"--color-primary-50": "231 241 252", // #e7f1fc
"--color-primary-100": "224 236 251", // #e0ecfb
"--color-primary-200": "216 231 250", // #d8e7fa
"--color-primary-300": "192 217 247", // #c0d9f7
"--color-primary-400": "145 189 240", // #91bdf0
"--color-primary-500": "98 160 234", // #62a0ea
"--color-primary-600": "88 144 211", // #5890d3
"--color-primary-700": "74 120 176", // #4a78b0
"--color-primary-800": "59 96 140", // #3b608c
"--color-primary-900": "48 78 115", // #304e73
// secondary | #99c1f1
"--color-secondary-50": "240 246 253", // #f0f6fd
"--color-secondary-100": "235 243 252", // #ebf3fc
"--color-secondary-200": "230 240 252", // #e6f0fc
"--color-secondary-300": "214 230 249", // #d6e6f9
"--color-secondary-400": "184 212 245", // #b8d4f5
"--color-secondary-500": "153 193 241", // #99c1f1
"--color-secondary-600": "138 174 217", // #8aaed9
"--color-secondary-700": "115 145 181", // #7391b5
"--color-secondary-800": "92 116 145", // #5c7491
"--color-secondary-900": "75 95 118", // #4b5f76
// tertiary | #f8e45c
"--color-tertiary-50": "254 251 231", // #fefbe7
"--color-tertiary-100": "254 250 222", // #fefade
"--color-tertiary-200": "253 248 214", // #fdf8d6
"--color-tertiary-300": "252 244 190", // #fcf4be
"--color-tertiary-400": "250 236 141", // #faec8d
"--color-tertiary-500": "248 228 92", // #f8e45c
"--color-tertiary-600": "223 205 83", // #dfcd53
"--color-tertiary-700": "186 171 69", // #baab45
"--color-tertiary-800": "149 137 55", // #958937
"--color-tertiary-900": "122 112 45", // #7a702d
// success | #33d17a
"--color-success-50": "224 248 235", // #e0f8eb
"--color-success-100": "214 246 228", // #d6f6e4
"--color-success-200": "204 244 222", // #ccf4de
"--color-success-300": "173 237 202", // #adedca
"--color-success-400": "112 223 162", // #70dfa2
"--color-success-500": "51 209 122", // #33d17a
"--color-success-600": "46 188 110", // #2ebc6e
"--color-success-700": "38 157 92", // #269d5c
"--color-success-800": "31 125 73", // #1f7d49
"--color-success-900": "25 102 60", // #19663c
// warning | #ffa348
"--color-warning-50": "255 241 228", // #fff1e4
"--color-warning-100": "255 237 218", // #ffedda
"--color-warning-200": "255 232 209", // #ffe8d1
"--color-warning-300": "255 218 182", // #ffdab6
"--color-warning-400": "255 191 127", // #ffbf7f
"--color-warning-500": "255 163 72", // #ffa348
"--color-warning-600": "230 147 65", // #e69341
"--color-warning-700": "191 122 54", // #bf7a36
"--color-warning-800": "153 98 43", // #99622b
"--color-warning-900": "125 80 35", // #7d5023
// error | #f66151
"--color-error-50": "254 231 229", // #fee7e5
"--color-error-100": "253 223 220", // #fddfdc
"--color-error-200": "253 216 212", // #fdd8d4
"--color-error-300": "251 192 185", // #fbc0b9
"--color-error-400": "249 144 133", // #f99085
"--color-error-500": "246 97 81", // #f66151
"--color-error-600": "221 87 73", // #dd5749
"--color-error-700": "185 73 61", // #b9493d
"--color-error-800": "148 58 49", // #943a31
"--color-error-900": "121 48 40", // #793028
// surface | #deddda
"--color-surface-50": "250 250 249", // #fafaf9
"--color-surface-100": "248 248 248", // #f8f8f8
"--color-surface-200": "247 247 246", // #f7f7f6
"--color-surface-300": "242 241 240", // #f2f1f0
"--color-surface-400": "232 231 229", // #e8e7e5
"--color-surface-500": "222 221 218", // #deddda
"--color-surface-600": "200 199 196", // #c8c7c4
"--color-surface-700": "167 166 164", // #a7a6a4
"--color-surface-800": "133 133 131", // #858583
"--color-surface-900": "109 108 107", // #6d6c6b
}
}

103
osit_ae_theme_3.ts Normal file
View File

@@ -0,0 +1,103 @@
import type { CustomThemeConfig } from '@skeletonlabs/tw-plugin';
export const myCustomTheme: CustomThemeConfig = {
name: 'my-custom-theme',
properties: {
// =~= Theme Properties =~=
"--theme-font-family-base": `Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'`,
"--theme-font-family-heading": `Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'`,
"--theme-font-color-base": "0 0 0",
"--theme-font-color-dark": "255 255 255",
"--theme-rounded-base": "16px",
"--theme-rounded-container": "8px",
"--theme-border-base": "1px",
// =~= Theme On-X Colors =~=
"--on-primary": "0 0 0",
"--on-secondary": "0 0 0",
"--on-tertiary": "0 0 0",
"--on-success": "0 0 0",
"--on-warning": "0 0 0",
"--on-error": "0 0 0",
"--on-surface": "0 0 0",
// =~= Theme Colors =~=
// primary | #3584e4
"--color-primary-50": "225 237 251", // #e1edfb
"--color-primary-100": "215 230 250", // #d7e6fa
"--color-primary-200": "205 224 248", // #cde0f8
"--color-primary-300": "174 206 244", // #aecef4
"--color-primary-400": "114 169 236", // #72a9ec
"--color-primary-500": "53 132 228", // #3584e4
"--color-primary-600": "48 119 205", // #3077cd
"--color-primary-700": "40 99 171", // #2863ab
"--color-primary-800": "32 79 137", // #204f89
"--color-primary-900": "26 65 112", // #1a4170
// secondary | #99c1f1
"--color-secondary-50": "240 246 253", // #f0f6fd
"--color-secondary-100": "235 243 252", // #ebf3fc
"--color-secondary-200": "230 240 252", // #e6f0fc
"--color-secondary-300": "214 230 249", // #d6e6f9
"--color-secondary-400": "184 212 245", // #b8d4f5
"--color-secondary-500": "153 193 241", // #99c1f1
"--color-secondary-600": "138 174 217", // #8aaed9
"--color-secondary-700": "115 145 181", // #7391b5
"--color-secondary-800": "92 116 145", // #5c7491
"--color-secondary-900": "75 95 118", // #4b5f76
// tertiary | #f8e45c
"--color-tertiary-50": "254 251 231", // #fefbe7
"--color-tertiary-100": "254 250 222", // #fefade
"--color-tertiary-200": "253 248 214", // #fdf8d6
"--color-tertiary-300": "252 244 190", // #fcf4be
"--color-tertiary-400": "250 236 141", // #faec8d
"--color-tertiary-500": "248 228 92", // #f8e45c
"--color-tertiary-600": "223 205 83", // #dfcd53
"--color-tertiary-700": "186 171 69", // #baab45
"--color-tertiary-800": "149 137 55", // #958937
"--color-tertiary-900": "122 112 45", // #7a702d
// success | #33d17a
"--color-success-50": "224 248 235", // #e0f8eb
"--color-success-100": "214 246 228", // #d6f6e4
"--color-success-200": "204 244 222", // #ccf4de
"--color-success-300": "173 237 202", // #adedca
"--color-success-400": "112 223 162", // #70dfa2
"--color-success-500": "51 209 122", // #33d17a
"--color-success-600": "46 188 110", // #2ebc6e
"--color-success-700": "38 157 92", // #269d5c
"--color-success-800": "31 125 73", // #1f7d49
"--color-success-900": "25 102 60", // #19663c
// warning | #ffa348
"--color-warning-50": "255 241 228", // #fff1e4
"--color-warning-100": "255 237 218", // #ffedda
"--color-warning-200": "255 232 209", // #ffe8d1
"--color-warning-300": "255 218 182", // #ffdab6
"--color-warning-400": "255 191 127", // #ffbf7f
"--color-warning-500": "255 163 72", // #ffa348
"--color-warning-600": "230 147 65", // #e69341
"--color-warning-700": "191 122 54", // #bf7a36
"--color-warning-800": "153 98 43", // #99622b
"--color-warning-900": "125 80 35", // #7d5023
// error | #f66151
"--color-error-50": "254 231 229", // #fee7e5
"--color-error-100": "253 223 220", // #fddfdc
"--color-error-200": "253 216 212", // #fdd8d4
"--color-error-300": "251 192 185", // #fbc0b9
"--color-error-400": "249 144 133", // #f99085
"--color-error-500": "246 97 81", // #f66151
"--color-error-600": "221 87 73", // #dd5749
"--color-error-700": "185 73 61", // #b9493d
"--color-error-800": "148 58 49", // #943a31
"--color-error-900": "121 48 40", // #793028
// surface | #deddda
"--color-surface-50": "250 250 249", // #fafaf9
"--color-surface-100": "248 248 248", // #f8f8f8
"--color-surface-200": "247 247 246", // #f7f7f6
"--color-surface-300": "242 241 240", // #f2f1f0
"--color-surface-400": "232 231 229", // #e8e7e5
"--color-surface-500": "222 221 218", // #deddda
"--color-surface-600": "200 199 196", // #c8c7c4
"--color-surface-700": "167 166 164", // #a7a6a4
"--color-surface-800": "133 133 131", // #858583
"--color-surface-900": "109 108 107", // #6d6c6b
}
}

5436
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,26 +1,68 @@
{
"name": "ae_sponsorships_app_svelte",
"name": "ae-app-svelte4-tailwind-skeleton",
"version": "0.1.5",
"private": true,
"version": "0.0.1",
"type": "module",
"scripts": {
"dev": "vite",
"dev": "vite dev",
"build": "vite build",
"build:prod": "cp .env.prod .env.production && vite build",
"build:staging": "cp .env.staging .env.production && vite build",
"preview": "vite preview",
"check": "svelte-check --tsconfig ./tsconfig.json"
"test": "npm run test:integration && npm run test:unit",
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
"lint": "prettier --check . && eslint .",
"format": "prettier --write .",
"test:integration": "playwright test",
"test:unit": "vitest"
},
"devDependencies": {
"@playwright/test": "^1.28.1",
"@skeletonlabs/skeleton": "^3.0.0-next.5",
"@skeletonlabs/skeleton-svelte": "^1.0.0-next.10",
"@skeletonlabs/tw-plugin": "^0.4.0",
"@sveltejs/adapter-auto": "^3.0.0",
"@sveltejs/adapter-node": "^5.0.0",
"@sveltejs/adapter-static": "^3.0.1",
"@sveltejs/vite-plugin-svelte": "^3.0.0",
"@tsconfig/svelte": "^5.0.0",
"svelte": "^4.2.8",
"svelte-check": "^3.6.0",
"tslib": "^2.6.0",
"typescript": "^5.3.0",
"vite": "^5.0.0"
"@sveltejs/kit": "^2.0.0",
"@sveltejs/vite-plugin-svelte": "^4.0.0-next",
"@tailwindcss/forms": "^0.5.7",
"@tailwindcss/typography": "^0.5.10",
"@types/eslint": "^9.0.0",
"@types/node": "^22.0.0",
"@typescript-eslint/eslint-plugin": "^8.9.0",
"@typescript-eslint/parser": "^8.9.0",
"autoprefixer": "^10.4.20",
"eslint": "^9.0.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-svelte": "^2.36.0-next",
"flowbite": "^2.5.2",
"flowbite-svelte": "^0.46.23",
"flowbite-svelte-icons": "^1.6.2",
"highlight.js": "^11.10.0",
"postcss": "^8.4.41",
"prettier": "^3.1.1",
"prettier-plugin-svelte": "^3.1.2",
"svelte": "^5.0.0-next",
"svelte-check": "^4.0.0",
"svelte-highlight": "^7.7.0",
"tailwindcss": "^3.4.10",
"tslib": "^2.4.1",
"typescript": "^5.0.0",
"typescript-svelte-plugin": "^0.3.41",
"vite": "^5.4.0",
"vite-plugin-tailwind-purgecss": "^0.3.3",
"vitest": "^2.1.0"
},
"type": "module",
"dependencies": {
"aether_npm_lib": "bitbucket:oneskyit/one-sky-it-npm-library",
"axios": "^1.6.0"
"@floating-ui/dom": "^1.6.3",
"@popperjs/core": "^2.11.8",
"axios": "^1.6.7",
"dayjs": "^1.11.10",
"dexie": "^4.0.1-beta.14",
"html5-qrcode": "^2.3.8",
"svelte-persisted-store": "^0.11.0",
"tailwind-merge": "^2.5.0"
}
}

12
playwright.config.ts Normal file
View File

@@ -0,0 +1,12 @@
import type { PlaywrightTestConfig } from '@playwright/test';
const config: PlaywrightTestConfig = {
webServer: {
command: 'npm run build && npm run preview',
port: 4173
},
testDir: 'tests',
testMatch: /(.+\.)?(test|spec)\.[jt]s/
};
export default config;

6
postcss.config.cjs Normal file
View File

@@ -0,0 +1,6 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}

View File

@@ -1,175 +0,0 @@
// These localStorage values were created when generating the HTML
// let ae_local = window.localStorage.getItem('ae'); // Includes: cfg, client, page, other
// let ae_session = window.sessionStorage.getItem('ae'); // Includes: cfg, client, page, other
// let ae_com_local = window.localStorage.getItem('ae_com');
// let ae_com_session = window.sessionStorage.getItem('ae_com');
if (window.localStorage.getItem('ae') === null) {
window.localStorage.setItem('ae', JSON.stringify({ 'cfg': {}, 'client': {}, 'page': {}, 'other': {}, 'test': {} }));
}
if (window.sessionStorage.getItem('ae') === null) {
window.sessionStorage.setItem('ae', JSON.stringify({ 'cfg': {}, 'client': {}, 'page': {}, 'other': {}, 'test': {} }));
}
// JSON.parse(window.sessionStorage.getItem('ae'))
// export let ae_bridge = {
const ae_bridge = {
// example_var: 'Example Default Value',
// get example() {
// return this.example_var;
// },
// set example(new_value) {
// this.example_var = new_value;
// this.example_var_listener(new_value);
// this.example_var_core_listener(new_value);
// this.example_var_mods_listener(new_value);
// },
// example_var_listener: function (new_value) {},
// registerNewListener: function (external_listener_function) {
// this.example_var_listener = external_listener_function;
// },
// example_var_core_listener: function (new_value) {},
// registerNewCoreListener: function (external_core_listener_function) {
// this.example_var_core_listener = external_core_listener_function;
// },
// example_var_mods_listener: function (new_value) {},
// registerNewModsListener: function (external_mods_listener_function) {
// this.example_var_mods_listener = external_mods_listener_function;
// },
// Monitor change in **local** storage AE
// Created and set when generating and then rendering the inital HTML and JS
// ae_local_var: true,
ae_local_var: JSON.parse(window.localStorage.getItem('ae')),
get ae_local() {
return this.ae_local_var;
},
set ae_local(new_value) {
console.log('ae_local_var: new_value: ', new_value);
this.ae_local_var = new_value;
this.ae_local_listener(new_value);
window.localStorage.setItem('ae', new_value);
},
ae_local_listener: function (new_value) {},
register_ae_local_listener: function (external_listener_function) {
this.ae_local_listener = external_listener_function;
},
// Monitor change in **session* storage AE
// Created and set when generating and then rendering the inital HTML and JS
// ae_session_var: true,
// ae_session_var: JSON.parse((window.sessionStorage.getItem('ae') ? window.sessionStorage.getItem('ae') : {'cfg': true, 'client': true, 'page': true, 'other': true})),
// ae_session_var: {'example': 'This is just an example from init.js!'},
ae_session_var: JSON.parse(window.sessionStorage.getItem('ae')),
get ae_session() {
return this.ae_session_var;
},
set ae_session(new_value) {
console.log('ae_session_var: new_value: ', new_value);
this.ae_session_var = new_value;
this.ae_session_listener(new_value);
window.sessionStorage.setItem('ae', new_value);
},
ae_session_listener: function (new_value) {},
register_ae_session_listener: function (external_listener_function) {
this.ae_session_listener = external_listener_function;
},
// Monitor change in Access Type
access_type_var: 'anonymous',
get access_type() {
return this.access_type_var;
},
set access_type(new_value) {
this.access_type_var = new_value;
this.access_type_var_core_listener(new_value);
this.access_type_var_mods_listener(new_value);
},
access_type_var_core_listener: function (new_value) {},
register_core_access_type_listener: function (external_core_listener_function) {
this.access_type_var_core_listener = external_core_listener_function;
},
access_type_var_mods_listener: function (new_value) {},
register_mods_access_type_listener: function (external_mods_listener_function) {
this.access_type_var_mods_listener = external_mods_listener_function;
},
// Monitor change in AE Common
// ae_com_var: true,
ae_com_var: JSON.parse(window.localStorage.getItem('ae_com')),
get ae_com() {
return this.ae_com_var;
},
set ae_com(new_value) {
this.ae_com_var = new_value;
this.ae_com_var_core_listener(new_value);
this.ae_com_var_mods_listener(new_value);
},
ae_com_var_core_listener: function (new_value) {},
register_core_ae_com_listener: function (external_core_listener_function) {
this.ae_com_var_core_listener = external_core_listener_function;
},
ae_com_var_mods_listener: function (new_value) {},
register_mods_ae_com_listener: function (external_mods_listener_function) {
this.ae_com_var_mods_listener = external_mods_listener_function;
},
// Monitor change in Client
client_var: true,
get client() {
return this.client_var;
},
set client(new_value) {
this.client_var = new_value;
this.client_var_core_listener(new_value);
this.client_var_mods_listener(new_value);
},
client_var_core_listener: function (new_value) {},
register_core_client_listener: function (external_core_listener_function) {
this.client_var_core_listener = external_core_listener_function;
},
client_var_mods_listener: function (new_value) {},
register_mods_client_listener: function (external_mods_listener_function) {
this.client_var_mods_listener = external_mods_listener_function;
},
};
console.log('ae_bridge_init.js loaded');
// Updated: 2024-02-09
/* BEGIN: Add this to the stores.ts */
// This adds a listener to the ae_bridge object. This can then be exported and used in the Svelte components.
// export let ae_example = writable(ae_bridge.ae_example);
// ae_bridge.register_ae_example_listener((new_value) => {
// console.log(`AE Bridge: AE Example: ${new_value}`);
// console.log(new_value);
// ae_example.set(new_value);
// console.log(ae_example);
// });
/* END: Add this to the stores.ts */
/* BEGIN: Add this to the Svelte components */
// import { ae_example } from './stores';
/* END: Add this to the Svelte components */

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -1,239 +0,0 @@
<script lang="ts">
type key_val = {
[key: string]: any;
};
// *** Import Svelte core
import { onMount } from 'svelte';
// *** Import Aether core variables and functions
import { ae, api, Element_modal_v3 } from 'aether_npm_lib';
import { slct, slct_trigger, ae_app, ae_session, ae_local } from './stores';
export let ae_obj_type: string = 'example';
export let ae_obj_id: string = 'abc123';
// let data_store_obj_get_promise: Promise<any>;
let data_store_obj_get_promises: key_val = {};
let get_ds_hub_site_header_promise = handle_get_data_store_obj_w_code({code: 'hub_site_header'});
let get_ds_hub_site_footer_promise = handle_get_data_store_obj_w_code({code: 'hub_site_footer'});
handle_build_site_nav_menu();
onMount(() => {
console.log('** Component Mounted: ** OSIT - AE Hub: Main');
$ae_session.test.hub = 'Hello World!';
$ae_session.test.general = 'Hello world from The Hub!';
console.log('ae_session:', $ae_session);
});
async function handle_get_data_store_obj_w_code({code, data_type='text'}) {
console.log('*** handle_get_data_store_obj_w_code() ***');
let get_item_result = window.localStorage.getItem(code);
if (get_item_result) {
$ae_app.hub.ds[code] = get_item_result;
} else {
console.log('Get local storage item miss.');
}
data_store_obj_get_promises[code] = api.get_data_store_obj_w_code({
api_cfg: $ae_app.ae_api,
data_store_code: code,
data_type: data_type,
log_lvl: 0
})
.then(function (get_data_store_result) {
if (get_data_store_result) {
if (data_type == 'text') {
// console.log(get_data_store_result.text);
$ae_app.hub.ds[code] = get_data_store_result.text;
} else if (data_type == 'json') {
// console.log(get_data_store_result.json);
$ae_app.hub.ds[code] = get_data_store_result.json;
}
// console.log(`Code: ${$ae_app.hub.ds[code]}`);
// console.log(`Code:`, $ae_app.hub.ds[code]);
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
});
}
// In most cases we are just inserting HTML into the DOM. The Svelte module apps can update the ID's of the elements within if needed.
$: if ($ae_app.hub.ds['hub_site_header']) {
console.log('Hub Site Header:', $ae_app.hub.ds['hub_site_header']);
const site_header_element = document.getElementById('Site-Header');
if (site_header_element) {
site_header_element.innerHTML = $ae_app.hub.ds['hub_site_header'];
}
}
$: if ($ae_app.hub.ds['hub_site_footer']) {
console.log('Hub Site Footer:', $ae_app.hub.ds['hub_site_footer']);
const site_footer_element = document.getElementById('Site-Footer');
if (site_footer_element) {
site_footer_element.innerHTML = $ae_app.hub.ds['hub_site_footer'];
}
}
// $: if ($ae_app.hub.ds['hub_site_nav_menu']) {
// console.log('Hub Site Nav Menu:', $ae_app.hub.ds['hub_site_nav_menu']);
// const site_menu_element = document.getElementById('Site-Nav-Menu');
// if (site_menu_element) {
// /* Add the HTML to the site_menu_element DOM element */
// // site_menu_element.innerHTML = $ae_app.hub.ds['hub_site_nav_menu'];
// }
// }
$: if ($ae_app.hub.ds['hub_notifications']) {
console.log('Hub Notifications:', $ae_app.hub.ds['hub_notifications']);
const site_notifications_element = document.getElementById('Notifications');
if (site_notifications_element) {
site_notifications_element.innerHTML = $ae_app.hub.ds['hub_notifications'];
}
}
// if $ae_app.hub.ds['hub_site_header'] {
// console.log('Hub Site Header:', $ae_app.hub.ds['hub_site_header']);
// document.getElementById('Site-Header').innerHTML = $ae_app.hub.ds['hub_site_header'];
// }
function handle_build_site_nav_menu() {
$ae_session.site_nav_menu = {};
// let menu_item_tmp = {};
// Navigation button group
// $ae_session.site_nav_menu['options'] = []; // group
$ae_session.site_nav_menu['home'] = {
'access_level': 'all',
'state': 'active', // active, inactive, disabled
'text': '<span class="fas fa-home"></span> Home',
'href': '/',
'action': 'navigate', // navigate, modal, action
'class_li': ['ae_btn', 'btn_outline_primary']
};
$ae_session.site_nav_menu['reports_exports'] = {
'access_level': 'trusted',
'state': 'active', // active, inactive, disabled
'text': 'Reports & Exports',
'href': '/',
'action': 'navigate', // navigate, modal, action
'class_li': ['ae_btn', 'btn_outline_secondary']
};
$ae_session.site_nav_menu['manage'] = {
'access_level': 'administrator',
'state': 'active', // active, inactive, disabled
'text': 'Manage',
'href': '/manage',
'action': 'navigate', // navigate, modal, action
'class_li': ['ae_btn', 'btn_outline_secondary']
};
$ae_session.site_nav_menu['help'] = {
'access_level': 'all',
'state': 'active', // active, inactive, disabled
'text': 'Help',
'href': '/',
'class_li': ['ae_btn', 'btn_outline_secondary']
};
// // Trusted button group
// $ae_session.site_nav_menu['trusted'] = []; // group
// menu_item_tmp = $event_defaults.event_manage_btn;
// menu_item_tmp['href'] = `/event/${$slct.event_id}/manage`;
// menu_item_tmp['class_li'].push('btn_sm', 'btn_outline_warning');
// $ae_session.site_nav_menu['trusted'].push(menu_item_tmp);
// menu_item_tmp = $event_defaults.event_location_view_li_btn;
// menu_item_tmp['href'] = `/event/${$slct.event_id}/locations`;
// menu_item_tmp['class_li'].push('btn_sm', 'btn_outline_secondary');
// $ae_session.site_nav_menu['trusted'].push(menu_item_tmp);
// // Admin button group
// $ae_session.site_nav_menu['admin'] = []; // group
// menu_item_tmp = $event_defaults.event_edit_btn;
// menu_item_tmp['href'] = `/event/${$slct.event_id}/edit`;
// menu_item_tmp['class_li'].push('btn_sm', 'btn_outline_warning');
// $ae_session.site_nav_menu['admin'].push(menu_item_tmp);
}
</script>
<section class="ae_hub ae_debug">
The Hub!
<button
on:click={() => {
$ae_session.site_nav_menu['home'].text = '<span class="fas fa-house-damage"></span> Home';
// console.log('ae_session:', $ae_session);
$ae_local.testing = 'Hello World!';
$ae_local.test = 'Hello World!';
// $ae_local.set('Hello World!');
console.log('ae_local:', $ae_local);
}}
>
<span class="fas fa-biohazard"></span> Test
</button>
{#if $ae_app.administrator_access}
<span class="access_type administrator_access">Administrator</span>
{:else if $ae_app.trusted_access}
<span class="access_type trusted_access">Trusted</span>
{/if}
<div>
<!-- {$ae_session.test.example} -->
<!-- {$ae_session.test.general} -->
<!-- {$ae_session.test.hub} -->
<!-- {$ae_session.test.sponsorships} -->
</div>
{#await data_store_obj_get_promises['hub_site_header']}
<p>Loading site header...</p>
{:then}
<p>Site header loaded.</p>
<!-- <div class="">{@html $ae_app.hub.ds['hub_site_header']}</div> -->
<!-- <pre>
{$ae_app.hub.ds['hub_site_header']}
</pre> -->
{:catch error}
<p style="color: red">{error.message}</p>
{/await}
{#await data_store_obj_get_promises['hub_site_footer']}
<p>Loading site footer...</p>
{:then}
<p>Site footer loaded.</p>
<!-- <div class="">{@html $ae_app.hub.ds['hub_site_footer']}</div> -->
<!-- <pre>
{$ae_app.hub.ds['hub_site_footer']}
</pre> -->
{:catch error}
<p style="color: red">{error.message}</p>
{/await}
</section>
<style>
/* .ae_hub.ae_debug {
} */
</style>

View File

@@ -1,847 +0,0 @@
<script lang="ts">
type key_val = {
[key: string]: any;
};
// *** Import Svelte core
import { onMount } from 'svelte';
// *** Import Aether core variables and functions
import { ae, api, Element_modal_v3 } from 'aether_npm_lib';
import { slct, slct_trigger, ae_app, ae_local, ae_session } from './stores';
// *** Import Aether core components
// import { get_data_store_obj_w_code } from '../data_store/stores_data_store_api.js';
// *** Import Aether module variables and functions
// *** Import Aether module components
import Edit_sponsorship_obj from './10_edit__sponsorship_obj.svelte';
import List_sponsorship_obj from './10_list__sponsorship_obj.svelte';
import View_sponsorship_obj from './10_view__sponsorship_obj.svelte';
// *** Export/Exposed variables and functions for component
// export let account_id: string = $page['page_for']['account_id'];
export let account_id: string = $ae_app.account_id;
export let sponsorship_id: string = $ae_app.sponsorships.sponsorship_id;
export let user: string = $ae_app.user;
export let key: string = $ae_app.key;
export let full_name: string = $ae_app.full_name;
export let ae_admin_li: string = $ae_app.ae_admin_li;
export let ae_trusted_li: string = $ae_app.ae_trusted_li;
// *** Set initial variables
$ae_app.user = decodeURIComponent(user);
$ae_app.key = decodeURIComponent(key);
// $ae_app.ae_admin_li = ae_admin_li;
// $ae_app.ae_trusted_li = ae_trusted_li;
$ae_app.current_timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
if (!$ae_app.lu_country_subdivision_list) {
$ae_app.lu_country_subdivision_list = [];
}
if (!$ae_app.lu_country_list ) {
$ae_app.lu_country_list = [];
}
if (!$ae_app.lu_timezone_list) {
$ae_app.lu_timezone_list = [];
}
$ae_app.sponsorships.show_main__options = true; // Section for: search area, buttons for filtering sponsorships, create new sponsorship.
$ae_app.sponsorships.show_list__sponsorship_obj_li = true;
$ae_app.sponsorships.fulltext_search_qry_str = '';
$ae_app.sponsorships.qry_virtual = false;
$ae_app.sponsorships.qry_physical = false;
$ae_app.sponsorships.qry_type = '';
// NOTE: Check if the ae_user is in the ae_admin_li list
if ($ae_app.ae_user && $ae_app.ae_admin_li) {
if ($ae_app.ae_admin_li.includes($ae_app.ae_user)) {
$ae_app.access_type = 'administrator';
$ae_app.administrator_access = true;
$ae_app.trusted_access = true;
}
}
// NOTE: Check if the ae_user is in the ae_trusted_li list
if ($ae_app.ae_user && $ae_app.ae_trusted_li) {
if ($ae_app.ae_trusted_li.includes($ae_app.ae_user)) {
$ae_app.access_type = 'trusted';
$ae_app.trusted_access = true;
}
}
if ($ae_app.administrator_access) {
$ae_app.sponsorships.enabled = 'enabled';
$ae_app.sponsorships.hidden = 'not_hidden';
$ae_app.sponsorships.limit = 150;
} else if ($ae_app.trusted_access) {
$ae_app.sponsorships.enabled = 'enabled';
$ae_app.sponsorships.hidden = 'not_hidden';
$ae_app.sponsorships.limit = 75;
} else {
$ae_app.sponsorships.enabled = 'enabled';
$ae_app.sponsorships.hidden = 'not_hidden';
$ae_app.sponsorships.limit = 25;
}
let ae_sponsorship_obj_li_get_promise;
let ae_sponsorship_obj_get_promise;
let data_store_obj_get_promise;
let get_ds_sponsorships_info_promise = handle_get_data_store_obj_w_code({code: 'sponsorships_info'});
let get_ds_sponsorships_options_promise = handle_get_data_store_obj_w_code({code: 'sponsorships_options'});
if (account_id) {
$slct.account_id = account_id;
handle_load_ae_sponsorship_obj_li({account_id: $slct.account_id, try_cache: false});
}
// NOTE: This if sponsorship_id is not fully ready yet -2023-09-08
if (sponsorship_id) {
console.log(`Selected Sponsorship ID: ${sponsorship_id}`);
$slct.sponsorship_id = sponsorship_id;
$slct_trigger = 'load__sponsorship_obj';
// handle_load_sponsorship_id_obj({sponsorship_id: $slct.sponsorship_id, try_cache: false});
// // Auto show the selected Sponsorship ID
// // Set the URL param "sponsorship_id" to the current Sponsorship ID. This is a just in case.
// const url = new URL(location);
// url.searchParams.set('sponsorship_id', $slct.sponsorship_id);
// history.pushState({}, '', url);
// let message = {'sponsorship_id': $slct.sponsorship_id};
// window.parent.postMessage(message, "*");
$ae_app.sponsorships.show_main__options = true;
$ae_app.sponsorships.show_list__sponsorship_obj_li = true;
$ae_app.sponsorships.show_view__sponsorship_obj = true;
$ae_app.sponsorships.show_edit__sponsorship_obj = false;
}
if (!$ae_app.client_content) {
$ae_app.client_content = {};
}
onMount(() => {
console.log('** Component Mounted: ** OSIT - AE Sponsorships: Main');
document.getElementById('meeting_fulltext_search_qry_str').focus();
$ae_session.test.sponsorships = 'Hello World!';
$ae_session.test.general = 'Hello world from Sponsorships!';
console.log('ae_session:', $ae_session);
});
$: if ($ae_app.iframe_height && $ae_app.iframe_height_modal_body) {
console.log('getting new dimensions for iframe:', $ae_app.iframe_height, $ae_app.iframe_height_modal_body);
let iframe_height = 0;
if ($ae_app.iframe_height > $ae_app.iframe_height_modal_body) {
iframe_height = $ae_app.iframe_height;
} else {
iframe_height = $ae_app.iframe_height_modal_body;
// console.log($ae_app.modal_dimensions);
if ($ae_app.modal_dimensions && $ae_app.modal_dimensions.header_height) {
iframe_height = iframe_height + $ae_app.modal_dimensions.header_height;
}
if ($ae_app.modal_dimensions && $ae_app.modal_dimensions.footer_height) {
iframe_height = iframe_height + $ae_app.modal_dimensions.footer_height;
}
// iframe_height = iframe_height + 50; // Just in case
}
console.log(`Suggested new iframe_height: ${iframe_height}`);
window.parent.postMessage({'iframe_height': iframe_height}, "*"); // This should be in pixels
} else if ($ae_app.iframe_height) {
console.log('setting new iframe_height:', $ae_app.iframe_height);
// let iframe_height = $ae_app.iframe_height;
window.parent.postMessage({'iframe_height': $ae_app.iframe_height}, "*"); // This should be in pixels
}
$: if ($slct_trigger == 'load__sponsorship_obj_li' && $slct.account_id) {
if ($ae_app.sponsorships.qry_status == 'loading') {
console.log('*** $ae_app.sponsorships.qry_status == loading ***');
setTimeout(() => {
console.log("Delayed for X second.");
$slct_trigger = null;
handle_load_ae_sponsorship_obj_li({account_id: $slct.account_id, try_cache: false});
}, 250);
} else {
console.log('*** $ae_app.sponsorships.qry_status != loading ***');
$slct_trigger = null;
handle_load_ae_sponsorship_obj_li({account_id: $slct.account_id, try_cache: false});
}
}
async function handle_load_ae_sponsorship_obj_li({account_id, try_cache=true}) {
console.log('*** handle_load_ae_sponsorship_obj_li() ***');
console.log($ae_app.sponsorships);
let fulltext_search_qry_str = $ae_app.sponsorships.fulltext_search_qry_str;
let qry_virtual = $ae_app.sponsorships.qry_virtual;
let qry_physical = $ae_app.sponsorships.qry_physical;
let qry_type = $ae_app.sponsorships.qry_type;
let enabled = $ae_app.sponsorships.enabled;
let hidden = $ae_app.sponsorships.hidden;
let limit = $ae_app.sponsorships.limit;
let offset = $ae_app.sponsorships.offset;
let params = {};
// params['archived'] = 'all';
// params['conference'] = false;
// params['inc_address'] = true;
// params['inc_contact'] = true;
let params_json: key_val = {};
// if (fulltext_search_qry_str && fulltext_search_qry_str.length > 2) {
// params_json['ft_qry'] = {
// 'default_qry_str': fulltext_search_qry_str,
// 'location_address_json': fulltext_search_qry_str,
// 'contact_li_json': fulltext_search_qry_str,
// 'address_default_qry_str': fulltext_search_qry_str, // NOTE: Remove after going live with OSIT ae?
// 'contact_1_default_qry_str': fulltext_search_qry_str, // NOTE: Remove after going live with OSIT ae?
// };
// }
// if (qry_virtual || qry_physical || qry_type) {
// params_json['and_qry'] = {};
// if (qry_virtual) params_json['and_qry']['virtual'] = true;
// if (qry_physical) params_json['and_qry']['physical'] = true;
// if (qry_type) params_json['and_qry']['type'] = qry_type;
// }
// console.log('params_json:', params_json);
// console.log(params_json);
// NOTE: I am not sure if this is actually needed. It may save a little space in the URL.
// if (JSON.stringify(params_json) == JSON.stringify({})) {
// params_json = null;
// }
$ae_app.sponsorships.qry_status = 'loading';
ae_sponsorship_obj_li_get_promise = api.get_ae_obj_li_for_obj_id_crud({
api_cfg: $ae_app.ae_api,
obj_type: 'sponsorship',
for_obj_type: 'account',
for_obj_id: account_id,
use_alt_table: false, // NOTE: This will use the table_name_alt value instead of the table_name value in the API config.
use_alt_base: false, // NOTE: This will use the base_name_alt value instead of the base_name value in the API config.
enabled: enabled,
hidden: hidden,
order_by_li: {'priority': 'DESC', 'sort': 'DESC', 'updated_on': 'DESC', 'created_on': 'DESC'},
// order_by_li: {'priority': 'DESC', 'sort': 'DESC', 'created_on': 'DESC', 'updated_on': 'DESC'},
limit: limit,
offset: offset,
params_json: params_json,
params: params,
log_lvl: 2
})
.then(function (sponsorship_obj_li_get_result) {
if (sponsorship_obj_li_get_result) {
$slct.sponsorship_obj_li = sponsorship_obj_li_get_result;
console.log(`Sponsorship list:`, $slct.sponsorship_obj_li);
} else {
$slct.sponsorship_obj_li = [];
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
})
.finally(function () {
$ae_app.sponsorships.qry_status = 'done';
});
return ae_sponsorship_obj_li_get_promise;
}
$: if ($slct_trigger == 'load__sponsorship_obj' && $slct.sponsorship_id) {
$slct_trigger = null;
handle_load_sponsorship_id_obj({sponsorship_id: $slct.sponsorship_id, try_cache: false});
// Auto show the selected Sponsorship ID
// Is this pushState needed here?
// Set the URL param "sponsorship_id" to the current Sponsorship ID. This is a just in case.
// const url = new URL(location);
// url.searchParams.set('sponsorship_id', $slct.sponsorship_id);
// history.pushState({}, '', url);
// Is this postMessage needed here?
// let message = {'sponsorship_id': $slct.sponsorship_id};
// window.parent.postMessage(message, "*");
// $ae_app.sponsorships.show_main__options = false;
// $ae_app.sponsorships.show_list__sponsorship_obj_li = false;
// $ae_app.sponsorships.show_view__sponsorship_obj = true;
// $ae_app.sponsorships.show_edit__sponsorship_obj = false;
}
async function handle_load_sponsorship_id_obj({sponsorship_id, try_cache=false}) {
console.log('*** handle_load_sponsorship_id_obj() ***');
// let enabled = $ae_app.sponsorships.enabled;
// let hidden = $ae_app.sponsorships.hidden;
// let limit = $ae_app.sponsorships.limit;
// let offset = $ae_app.sponsorships.offset;
let params = {};
ae_sponsorship_obj_get_promise = api.get_ae_obj_id_crud({
api_cfg: $ae_app.ae_api,
obj_type: 'event',
obj_id: sponsorship_id,
use_alt_table: true, // NOTE: This will use the table_name_alt value instead of the table_name value in the API config.
use_alt_base: true, // NOTE: This will use the base_name_alt value instead of the base_name value in the API config.
params: params,
log_lvl: 0
})
.then(function (sponsorship_obj_get_result) {
if (sponsorship_obj_get_result) {
$slct.sponsorship_obj = sponsorship_obj_get_result;
console.log(`Sponsorship object:`, $slct.sponsorship_obj);
}
// Auto show the selected Sponsorship ID
// Is this pushState needed here?
// Set the URL param "sponsorship_id" to the current Sponsorship ID.
const url = new URL(location);
url.searchParams.set('sponsorship_id', $slct.sponsorship_id);
history.pushState({}, '', url);
// Is this postMessage needed here?
let message = {'sponsorship_id': $slct.sponsorship_id};
window.parent.postMessage(message, "*");
})
.catch(function (error) {
console.log('No results returned or failed.', error);
});
return ae_sponsorship_obj_get_promise;
}
function handle_created_sponsorship_obj(event) {
console.log('*** handle_created_sponsorship_obj() ***');
console.log(event.detail);
handle_load_sponsorship_id_obj({sponsorship_id: $slct.sponsorship_id, try_cache: false});
const url = new URL(location);
url.searchParams.set('sponsorship_id', $slct.sponsorship_id);
history.pushState({}, '', url);
let message = {'sponsorship_id': $slct.sponsorship_id};
window.parent.postMessage(message, "*");
// $slct_trigger = 'load__sponsorship_obj';
$slct_trigger = 'load__sponsorship_obj_li';
$ae_app.sponsorships.show_main__options = false;
$ae_app.sponsorships.show_list__sponsorship_obj_li = false;
$ae_app.sponsorships.show_view__sponsorship_obj = true;
$ae_app.sponsorships.show_edit__sponsorship_obj = false;
}
function handle_updated_sponsorship_obj(event) {
console.log('*** handle_updated_sponsorship_obj() ***');
console.log(event.detail);
// $slct_trigger = 'load__sponsorship_obj';
$slct_trigger = 'load__sponsorship_obj_li';
$ae_app.sponsorships.show_main__options = false;
$ae_app.sponsorships.show_list__sponsorship_obj_li = false;
$ae_app.sponsorships.show_view__sponsorship_obj = true;
$ae_app.sponsorships.show_edit__sponsorship_obj = false;
}
function handle_deleted_sponsorship_obj(event) {
console.log('*** handle_deleted_sponsorship_obj() ***');
console.log(event.detail);
const url = new URL(location);
url.searchParams.delete('sponsorship_id');
history.pushState({}, '', url);
let message = {'sponsorship_id': null};
window.parent.postMessage(message, "*");
$slct_trigger = 'load__sponsorship_obj_li';
$ae_app.sponsorships.show_main__options = true;
$ae_app.sponsorships.show_list__sponsorship_obj_li = true;
$ae_app.sponsorships.show_view__sponsorship_obj = false;
$ae_app.sponsorships.show_edit__sponsorship_obj = false;
}
function handle_submit_form(event) {
console.log('*** handle_submit_form() ***');
console.log(event);
event.preventDefault();
event.stopPropagation();
return false;
}
function handle_cancel_form(event) {
console.log('*** handle_cancel_form() ***');
console.log(event);
event.preventDefault();
event.stopPropagation();
return false;
}
function handle_oninput_fulltext_search_qry_str(event) {
console.log('*** handle_oninput_fulltext_search_qry_str() ***');
console.log(event);
// Check if this variable is a promise. The last query may still be being processed.
// if (!ae_sponsorship_obj_li_get_promise.promise) {
// console.log('*** handle_oninput_fulltext_search_qry_str() ***');
// console.log('*** Promise is still processing. ***');
// console.log(ae_sponsorship_obj_li_get_promise);
// ae_sponsorship_obj_li_get_promise.promise.finally(() => { ae_sponsorship_obj_li_get_promise.promise.done = true; });
// } else {
// $slct_trigger = 'load__sponsorship_obj_li';
// }
// if (ae_sponsorship_obj_li_get_promise && ae_sponsorship_obj_li_get_promise.then) {
// console.log('*** handle_oninput_fulltext_search_qry_str() ***');
// console.log('*** Promise is still processing. ***');
// console.log(ae_sponsorship_obj_li_get_promise);
// $slct_trigger = 'load__sponsorship_obj_li';
// return;
// }
// fulltext_search_qry_str = event.target.value;
// if ($ae_app.sponsorships.fulltext_search_qry_str.length > 2) {
// } else {
// $ae_app.sponsorships.fulltext_search_qry_str = '';
// }
$slct_trigger = 'load__sponsorship_obj_li';
}
async function handle_get_data_store_obj_w_code({code, data_type='text'}) {
console.log('*** handle_get_data_store_obj_w_code() ***');
let get_item_result = window.localStorage.getItem(code);
if (get_item_result) {
$ae_app.sponsorships.ds[code] = get_item_result;
} else {
console.log('Get local storage item miss.');
}
data_store_obj_get_promise = api.get_data_store_obj_w_code({
api_cfg: $ae_app.ae_api,
data_store_code: code,
data_type: data_type,
log_lvl: 1
})
.then(function (get_data_store_result) {
if (get_data_store_result) {
if (data_type == 'text') {
// console.log(get_data_store_result.text);
$ae_app.sponsorships.ds[code] = get_data_store_result.text;
} else if (data_type == 'json') {
// console.log(get_data_store_result.json);
$ae_app.sponsorships.ds[code] = get_data_store_result.json;
}
// console.log(`Code: ${$ae_app.sponsorships.ds[code]}`);
// console.log(`Code:`, $ae_app.sponsorships.ds[code]);
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
});
}
</script>
<!-- <svelte:window
bind:outerHeight={ae_iframe_height}
/> -->
<section id="osit_ae_sponsorships" class="osit_sponsorships ae_main c_ae c_ae_sponsorships ae_main" bind:clientHeight={$ae_app.iframe_height}>
<header>
<h1>Sponsorships for One Sky IT Demo</h1>
</header>
<section class="ae_section ae_meta">
<p>
ae: {($ae_app.ae_full_name ? $ae_app.ae_full_name : 'Name not set')}
<span class="details">
(
{($ae_app.ae_email ? $ae_app.ae_email : 'Email not set')}
{#if $ae_app.administrator_access}
<span class="access_type administrator_access">Administrator</span>
{:else if $ae_app.trusted_access}
<span class="access_type trusted_access">Trusted</span>
{/if}
<span class="ae_user">{$ae_app.ae_user ? $ae_app.ae_user : 'User not set'}</span>
)
</span>
</p>
</section>
<div class="ae_overview">
<div class="ae_info ds__sponsorships_info ">
{@html $ae_app.sponsorships.ds.sponsorships_info}
</div>
</div>
{#if $ae_app.sponsorships.show_main__options}
<section class="ae_section ae_options ae_column sponsorship_obj__options">
<div class="ae_note ds__sponsorships_options ">
{@html $ae_app.sponsorships.ds.sponsorships_options}
</div>
<div class="filters_and_search">
<form on:submit|preventDefault={handle_submit_form} on:keydown={e => e.key === 'Escape' && handle_cancel_form} class="search_form">
<div class="ae_group">
<input
type="search"
placeholder="Search (name, description, etc.)"
id="meeting_fulltext_search_qry_str"
name="fulltext_search_qry_str"
bind:value={$ae_app.sponsorships.fulltext_search_qry_str}
style="width: 50%;"
class="bs-input"
>
<button
on:click={handle_oninput_fulltext_search_qry_str}
>
<span class="fas fa-search"></span> Search
</button>
</div>
<fieldset>
<legend>Filter on?</legend>
<div class="ae_row ae_flex_justify_around ae_width_md">
<label>Paid
<input
name="qry_paid"
type="checkbox"
bind:checked={$ae_app.sponsorships.qry_paid}
on:change={() => {$slct_trigger = 'load__sponsorship_obj_li';}}
>
</label>
<label>Guests
<input
name="qry_guest_li"
type="checkbox"
bind:checked={$ae_app.sponsorships.qry_guest_li}
on:change={() => {$slct_trigger = 'load__sponsorship_obj_li';}}
>
</label>
</div>
</fieldset>
<fieldset>
<legend>Select level?</legend>
<div class="ae_row ae_flex_justify_around ae_width_100">
<label>All
<input
name="qry_type"
type="radio"
value=""
bind:group={$ae_app.sponsorships.qry_type}
on:change={() => {$slct_trigger = 'load__sponsorship_obj_li';}}
title="Show all meeting types"
>
</label>
<label>Friend ($5,000)
<input
name="qry_type"
type="radio"
value="Friend"
bind:group={$ae_app.sponsorships.qry_type}
on:change={() => {$slct_trigger = 'load__sponsorship_obj_li';}}
title="Friend ($5,000)"
>
</label>
<label>Supporter ($7,500)
<input
name="qry_type"
type="radio"
value="Supporter"
bind:group={$ae_app.sponsorships.qry_type}
on:change={() => {$slct_trigger = 'load__sponsorship_obj_li';}}
title="Supporter ($7,500)"
>
</label>
<label>Champion ($12,500)
<input
name="qry_type"
type="radio"
value="Champion"
bind:group={$ae_app.sponsorships.qry_type}
on:change={() => {$slct_trigger = 'load__sponsorship_obj_li';}}
title="Champion ($12,500)"
>
</label>
<label>Advocate ($20,000)
<input
name="qry_type"
type="radio"
value="Advocate"
bind:group={$ae_app.sponsorships.qry_type}
on:change={() => {$slct_trigger = 'load__sponsorship_obj_li';}}
title="Advocate ($20,000)"
>
</label>
<label>Presenting Partner ($30,000)
<input
name="qry_type"
type="radio"
value="Presenting Partner"
bind:group={$ae_app.sponsorships.qry_type}
on:change={() => {$slct_trigger = 'load__sponsorship_obj_li';}}
title="Presenting Partner ($30,000)"
>
</label>
<label>Signature Partner ($50,000)
<input
name="qry_type"
type="radio"
value="Signature Partner"
bind:group={$ae_app.sponsorships.qry_type}
on:change={() => {$slct_trigger = 'load__sponsorship_obj_li';}}
title="Signature Partner ($50,000)"
>
</label>
</div>
</fieldset>
</form>
{#await ae_sponsorship_obj_li_get_promise}
<div><span class="fas fa-spinner"></span>
Loading sponsorships...</div>
{:then ae_sponsorship_obj_li_get_result}
<!-- <p>Sponsorship list: {ae_sponsorship_obj_li_get_result}</p> -->
{:catch error}
<div>Error: {error.message}</div>
{/await}
<div class="ae_group ae_row">
{#if $ae_app.trusted_access && $ae_app.sponsorships.hidden == 'not_hidden'}
<button
on:click={() => {
$ae_app.sponsorships.hidden = 'all';
$ae_app.sponsorships.limit = 150;
$slct_trigger = 'load__sponsorship_obj_li';
}}
class="btn_show_bb_post ae_btn btn btn-info"
>
<span class="fas fa-eye"></span> Show Hidden Sponsorships
</button>
{:else if $ae_app.trusted_access && $ae_app.sponsorships.hidden == 'all'}
<button
on:click={() => {
$ae_app.sponsorships.hidden = 'not_hidden';
$slct_trigger = 'load__sponsorship_obj_li';
}}
class="btn_hide_bb_post ae_btn btn btn-info"
>
<span class="fas fa-eye-slash"></span> Hide Hidden Sponsorships
</button>
{/if}
{#if $ae_app.administrator_access && $ae_app.sponsorships.enabled == 'enabled'}
<button
on:click={() => {
$ae_app.sponsorships.hidden = 'all';
$ae_app.sponsorships.enabled = 'all';
$ae_app.sponsorships.limit = 500;
$slct_trigger = 'load__sponsorship_obj_li';
}}
class="btn_show_bb_post ae_btn btn btn-warning"
>
<span class="fas fa-eye"></span> Show Disabled Sponsorships
</button>
{:else if $ae_app.administrator_access && $ae_app.sponsorships.enabled == 'all'}
<button
on:click={() => {
$ae_app.sponsorships.enabled = 'enabled';
$slct_trigger = 'load__sponsorship_obj_li';
}}
class="btn_hide_bb_post ae_btn btn btn-warning"
>
<span class="fas fa-eye-slash"></span> Hide Disabled Sponsorships
</button>
{/if}
<button
on:click={() => {
$slct.sponsorship_id = null;
$slct.sponsorship_obj = {};
const url = new URL(location);
url.searchParams.delete('sponsorship_id');
history.pushState({}, '', url);
$ae_app.sponsorships.show_main__options = false;
$ae_app.sponsorships.show_list__sponsorship_obj_li = false;
$ae_app.sponsorships.show_view__sponsorship_obj = false;
$ae_app.sponsorships.show_edit__sponsorship_obj = true;
$ae_session.test.sponsorships = 'Hello World! Create new Sponsorship was clicked!';
$ae_session.test_xyz.sponsorships = 'Hello World! Create new Sponsorship was clicked!';
}}
class="btn_new_recovery_meeting ae_btn btn btn-secondary"
>
<span class="fas fa-plus"></span> Create new Sponsorship
</button>
</div>
</div> <!-- END: div filters_and_search -->
</section>
{/if}
{#if $slct.sponsorship_obj_li && $ae_app.sponsorships.show_list__sponsorship_obj_li}
<List_sponsorship_obj />
{/if}
{#if $ae_app.sponsorships.show_edit__sponsorship_obj}
<!-- <section class="ae_edit sponsorship_obj sponsorship_id ae_sponsorship_id_edit"> -->
<Element_modal_v3
show = { true }
modal_cover_body = { false }
report_client_dimensions = { true }
on:close={ () => {
$ae_app.sponsorships.show_main__options = true;
$ae_app.sponsorships.show_list__sponsorship_obj_li = true;
$ae_app.sponsorships.show_edit__sponsorship_obj = false;
$ae_app.sponsorships.show_view__sponsorship_obj = false;
const url = new URL(location);
url.searchParams.delete('sponsorship_id');
history.pushState({}, '', url);
let message = {'sponsorship_id': null};
window.parent.postMessage(message, "*");
}}
on:report__modal_dimensions={ (event) => {
console.log('*** on:report__modal_dimensions ***');
console.log(event.detail);
$ae_app.modal_dimensions = event.detail.modal_dimensions;
}}
>
<span slot="header_title">{@html ($slct.sponsorship_obj.name ? $slct.sponsorship_obj.name : 'New Sponsorship')}</span>
<span slot="body">
<Edit_sponsorship_obj
on:created__meeting_obj={handle_created_sponsorship_obj}
on:updated__meeting_obj={handle_updated_sponsorship_obj}
on:deleted__meeting_obj={handle_deleted_sponsorship_obj}
/>
</span>
</Element_modal_v3>
<!-- </section> -->
{/if}
{#if $ae_app.sponsorships.show_view__sponsorship_obj && $slct.sponsorship_obj}
<!-- <section class="ae_view sponsorship_obj sponsorship_id ae_sponsorship_id_view"> -->
<Element_modal_v3
show = { true }
modal_cover_body = { false }
report_client_dimensions = { true }
on:close={ () => {
$slct.sponsorship_id = null;
$slct.sponsorship_obj = {};
$ae_app.sponsorships.show_main__options = true;
$ae_app.sponsorships.show_list__sponsorship_obj_li = true;
$ae_app.sponsorships.show_view__sponsorship_obj = false;
$ae_app.sponsorships.show_edit__sponsorship_obj = false;
const url = new URL(location);
url.searchParams.delete('sponsorship_id');
history.pushState({}, '', url);
let message = {'sponsorship_id': null};
window.parent.postMessage(message, "*");
}}
on:report__modal_dimensions={ (event) => {
console.log('*** on:report__modal_dimensions ***');
console.log(event.detail);
$ae_app.modal_dimensions = event.detail.modal_dimensions;
}}
>
<span slot="header_title">{@html $slct.sponsorship_obj.name}</span>
<span slot="body">
<View_sponsorship_obj />
</span>
</Element_modal_v3>
<!-- </section> -->
{/if}
</section>
<style>
/* .ae_meta {
font-size: smaller;
color: hsla(0,0%,50%,1);
} */
/* .ae_edit.sponsorship_obj {
border: dashed thin hsla(0,0%,70%,1);
margin: .5em .25em;
padding: .5em .25em;
background-color: hsla(0,0%,90%,1);
} */
/* .ae_view.sponsorship_obj {
border: dashed thin hsla(0,0%,70%,1);
margin: .5em .25em;
padding: .5em .25em;
background-color: hsla(0,0%,90%,1);
} */
/* :global(.ae_edit.sponsorship_id .element_ae_modal) {
border: dashed thin hsla(0,0%,70%,1);
margin: .5em .25em;
padding: .5em .25em;
background-color: hsla(0,0%,90%,1);
} */
</style>

File diff suppressed because it is too large Load Diff

View File

@@ -1,63 +0,0 @@
<script lang="ts">
// *** Import Svelte core
import { onMount } from 'svelte';
import { slct, slct_trigger, ae_app, ae_session } from './stores';
onMount(() => {
console.log('** Component Mounted: ** OSIT - AE Hub: Site Menu');
});
</script>
<nav>
{#if $ae_session.site_nav_menu}
<ul>
{#each Object.entries($ae_session.site_nav_menu) as [name, menu_item]}
<li>
<a href={menu_item.href} class={menu_item.class_li}>{@html menu_item.text}</a>
</li>
{/each}
</ul>
{/if}
</nav>
<style>
nav {
/* outline: dashed thick red; */
/* background-color: hsla(0, 0%, 100%, 0.85); */
/* padding: .5em 1em; */
display: flex;
justify-content: space-between;
}
nav ul {
list-style-type: none;
padding: 0;
width: 100%;
display: flex;
justify-content: space-around;
}
nav ul li {
/* display: inline; */
/* margin-right: 1em; */
}
nav ul li a {
text-decoration: none;
}
nav ul li a:hover {
text-decoration: underline;
}
nav ul li a.active {
font-weight: bold;
}
nav ul li a.active:hover {
text-decoration: none;
}
</style>

View File

@@ -1,261 +0,0 @@
<script lang="ts">
import { createEventDispatcher, onMount } from 'svelte';
import { fade } from 'svelte/transition';
import { ae, Element_modal_v3 } from 'aether_npm_lib';
import { slct, slct_trigger, ae_app } from './stores';
import Edit_post_comment_obj from './10_edit__post_comment_obj.svelte';
const dispatch = createEventDispatcher();
if ($slct.post_id) {
console.log(`Post ID selected: ${$slct.post_id}`);
console.log(`Post Object selected: ${$slct.post_obj}`)
$slct_trigger = 'load__post_obj';
}
onMount(() => {
console.log('** Component Mounted: ** View - Post Obj');
});
function handle_post_comment_obj_created(event) {
console.log('*** handle_post_comment_obj_created() ***');
console.log(event.detail);
$slct.post_comment_id = null;
$slct.post_comment_obj = {};
$slct_trigger = 'load__post_obj_li';
$slct_trigger = 'load__post_obj';
$slct_trigger = 'load__post_comment_obj_li';
// $ae_app.posts.show_post_list = false;
// $ae_app.posts.show_edit__post_id = false;
// $ae_app.posts.show_view__post_id = true;
$ae_app.posts.show_edit__post_comment = false;
}
function handle_post_comment_obj_updated(event) {
console.log('*** handle_post_comment_obj_updated() ***');
console.log(event.detail);
$slct_trigger = 'load__post_obj';
$slct_trigger = 'load__post_comment_obj_li';
// $ae_app.posts.show_post_list = false;
// $ae_app.posts.show_edit__post_id = false;
// $ae_app.posts.show_view__post_id = true;
$ae_app.posts.show_edit__post_comment = false;
}
function handle_post_comment_obj_deleted(event) {
console.log('*** handle_post_comment_obj_deleted() ***');
console.log(event.detail);
$slct_trigger = 'load__post_obj_li';
$slct_trigger = 'load__post_obj';
$slct_trigger = 'load__post_comment_obj_li';
// $ae_app.posts.show_post_list = false;
// $ae_app.posts.show_edit__post_id = false;
// $ae_app.posts.show_view__post_id = true;
$ae_app.posts.show_edit__post_comment = false;
}
</script>
<section
bind:clientHeight={$ae_app.iframe_height_modal_body}
class="svelte_component ae_section ae_view post_obj view__post_obj"
>
<div class="post__header">
<h2 class="post__title">
{@html $slct.post_obj.title}
{#if $slct.post_obj.topic_id}<span class="badge badge-info bg-info"><span class="fas fa-user-md"></span> {$slct.post_obj.topic_name}</span>{/if}
</h2>
</div>
<div class="post__content">{@html $slct.post_obj.content}</div>
<section class="ae_section ae_meta post__meta">
<div class="ae_group">
{#if ($slct.post_obj.anonymous)}
<div class="post__posted_by">
Posted by: <span class="fas fa-user-secret"></span> <span class="post__full_name">Anonymous</span>
</div>
{:else if ($slct.post_obj.full_name)}
<div class="post__posted_by">
Posted by: <span class="fas fa-user"></span> <span class="post__full_name">{$slct.post_obj.full_name}
{#if $ae_app.trusted_access && $slct.post_obj.email}
<a href="mailto:{$slct.post_obj.email}?subject=IDAA BB Post">{$slct.post_obj.email}</a>
{/if}
</div>
{/if}
<div class="post__created_on_updated_on">
{#if !$slct.post_obj.updated_on}
<span class="ae_label">Created on:</span>
<span class="ae_value post__created_on">{ae.util.iso_datetime_formatter($slct.post_obj.created_on, 'datetime_iso_no_seconds')}</span>
{:else}
<span class="ae_label">Updated on:</span>
<span class="ae_value post__updated_on">
{ae.util.iso_datetime_formatter($slct.post_obj.updated_on, 'datetime_iso_no_seconds')}</span>
{/if}
<span class="post__archive_on">
<span class="ae_label">Archive on:</span>
<span class="ae_value">{ae.util.iso_datetime_formatter($slct.post_obj.archive_on, 'datetime_iso_no_seconds')}</span>
</span>
</div>
</div>
<div class="ae_options">
{#if $slct.post_obj.post_comment_count}
<span class="ae_badge ae_info post__post_comment_count">
<span class="fas fa-comment"></span> {($slct.post_obj.post_comment_count == 1 ? `${$slct.post_obj.post_comment_count} comment` : `${$slct.post_obj.post_comment_count} comments` )}
</span>
{/if}
<button
on:click={() => {
$ae_app.posts.show_edit__post_comment = true;
}}
class="btn btn-primary"
title={`New comment on: ${$slct.post_obj.title}`}
>
<span class="fas fa-plus"></span> New Comment
</button>
{#if $ae_app.trusted_access || $slct.post_obj.external_person_id === $ae_app.novi_uuid || $slct.post_obj.email === $ae_app.novi_email}
<button
on:click={() => {
// $slct.post_id = $slct.post_obj.post_id_random;
// $slct.post_obj = $slct.post_obj;
// const url = new URL(location);
// url.searchParams.set('post_id', $slct.post_obj.post_id_random);
// history.pushState({}, '', url);
// $ae_app.posts.show_main__options = false;
// $ae_app.posts.show_list__post_li = false;
$ae_app.posts.show_view__post_id = false;
$ae_app.posts.show_edit__post_id = true;
}}
class="ae_btn ae_smallest btn btn-xs btn-secondary"
title={`Edit post: ${$slct.post_obj.name}`}
>
<span class="fas fa-edit"></span> Edit
</button>
{/if}
</div>
</section>
{#if $ae_app.posts.show_edit__post_comment}
<section class="bb_post_comment_crud">
<Element_modal_v3
show = { true }
modal_cover_body = { true }
on:close={ () => {
$slct.post_comment_id = null;
$slct.post_comment_obj = {};
// $ae_app.posts.show_post_list = true;
// $ae_app.posts.show_edit__post_id = false;
// $ae_app.posts.show_view__post_id = false;
$ae_app.posts.show_edit__post_comment = false;
}}
>
<span slot="header_title">Comment on: {($slct.post_obj.title ? $slct.post_obj.title : '')}</span>
<span slot="body">
<section class="post_comment_obj_view">
<Edit_post_comment_obj on:post_comment_obj_created={handle_post_comment_obj_created} on:post_comment_obj_updated={handle_post_comment_obj_updated} on:post_comment_obj_deleted={handle_post_comment_obj_deleted} />
</section>
</span>
</Element_modal_v3>
</section>
{/if}
{#if $slct.post_comment_obj_li.length}
{#each $slct.post_comment_obj_li as idaa_post_comment_obj, index}
<hr />
<div class="post_comment__content">{@html idaa_post_comment_obj.content}</div>
<section class="ae_section ae_meta post_comment__meta">
<div class="ae_group">
<span class="post_comment__posted_by `comment_by_container">
<span class="comment_by_lable">Comment by:</span>
{#if idaa_post_comment_obj.anonymous}
<span class="fas fa-user-secret"></span>
<span class="comment_by_full_name anonymous">Anonymous</span>
{:else}
<span class="fas fa-user"></span>
<span class="comment_by_full_name">{idaa_post_comment_obj.full_name}</span>
<!-- {#if idaa_post_comment_obj.email}
(<a href="mailto:{idaa_post_comment_obj.email}"><span class="comment_by_email">{idaa_post_comment_obj.email}</span></a>)
{/if} -->
{/if}
<div class="post_comment__created_on_updated_on">
Created on:
<span class="post_comment__created_on">{ae.util.iso_datetime_formatter(idaa_post_comment_obj.created_on, 'datetime_iso_no_seconds')}
{#if idaa_post_comment_obj.updated_on}
Updated on:
{ae.util.iso_datetime_formatter(idaa_post_comment_obj.updated_on, 'datetime_iso_no_seconds')}
{/if}
</div>
</div>
{#if $ae_app.trusted_access || idaa_post_comment_obj.external_person_id === $ae_app.novi_uuid}
<div class="ae_options">
<button on:click={() => {
$slct.post_comment_id = idaa_post_comment_obj.post_comment_id_random;
$slct.post_comment_obj = idaa_post_comment_obj;
// $ae_app.posts.show_post_comment_list = false;
$ae_app.posts.show_edit__post_comment = true;
// $ae_app.posts.show_view__post_id = false;
}}
class="ae_btn ae_smallest btn btn-secondary"
>
<span class="fas fa-edit"></span> Edit Comment
</button>
</div>
{/if}
</section>
{/each}
{/if}
</section>
<style>
.post_obj .ae_meta {
flex-direction: column;
/* justify-content: space-between; */
}
.post_obj .ae_meta .ae_group {
flex-direction: row;
}
.post_obj .ae_meta .ae_options {
flex-direction: row;
justify-content: space-between;
}
.post__posted_by, .post_comment__posted_by {
/* font-size: smaller; */
/* background-color: hsla(0,80%,50%,1); */
/* color: hsla(0,0%,50%,1); */
}
.post__created_on_updated_on, .post_comment__created_on_updated_on {
/* font-size: smaller; */
/* background-color: hsla(0,80%,50%,1); */
/* color: hsla(0,0%,50%,1); */
}
</style>

View File

@@ -1,192 +0,0 @@
<script lang="ts">
import { createEventDispatcher, onMount } from 'svelte';
import { fade } from 'svelte/transition';
import { ae } from 'aether_npm_lib';
import { slct, slct_trigger, ae_app } from './stores';
export let container_class_li = [];
const dispatch = createEventDispatcher();
if ($slct.sponsorship_id) {
console.log(`Sponsorship ID selected: ${$slct.sponsorship_id}`);
console.log(`Sponsorship Object selected: ${$slct.sponsorship_obj}`)
$slct_trigger = 'load__sponsorship_obj';
}
onMount(() => {
console.log('** Component Mounted: ** View - Sponsorship Obj');
});
dayjs.extend(window.dayjs_plugin_utc)
dayjs.extend(window.dayjs_plugin_timezone);
console.log(`UTC offset: ${dayjs().utcOffset()}`);
console.log(`TZ offset: ${dayjs().utcOffset('US/Pacific')}`);
// let test_time = dayjs.utc('2024-01-08 11:55').tz('Asia/Taipei');
// let test_time = dayjs.utc('2024-01-08 14:15').tz('America/New_York');
let test_time = dayjs.tz('2024-01-08 14:15', 'US/Pacific');
console.log(test_time.format('YYYY-MM-DD HH:mm'));
let adjusted_to_local_tz = test_time.tz('America/New_York');
console.log(adjusted_to_local_tz.format('YYYY-MM-DD HH:mm'));
let adjusted_to_local_tz_v2 = dayjs.tz('2024-01-08 14:15', 'US/Pacific').tz('America/New_York');
console.log(adjusted_to_local_tz_v2);
</script>
<section class="svelte_component ae_section ae_view sponsorship_obj view__sponsorship_obj {container_class_li.join(' ')}">
<div class="sponsorship__header">
<h2 class="sponsorship__name">{@html $slct.sponsorship_obj.name}</h2>
</div>
<div class="sponsorship__content">
<div
class="sponsorship_description description"
>
<div class="ae_label sponsorship__description">Description:</div>
<pre class="ae_value sponsorship__description">{@html $slct.sponsorship_obj.description ? $slct.sponsorship_obj.description : '-- No Description Given --'}</pre>
</div>
<div
class:ae_d_none={!$slct.sponsorship_obj.level_num}
class="sponsorship_level"
>
<span class="ae_label">Level of Sponsorship:</span>
<span class="ae_value"><span class="fas fa-gem"></span> {$slct.sponsorship_obj.level_num} &mdash; {$slct.sponsorship_obj.level_str}</span>
</div>
<div>
<span class="ae_label">Paid:</span>
$
<span class="ae_value">
{$slct.sponsorship_obj.paid ? 'Yes, marked as paid' : 'Not yet marked as paid'}
</span>
</div>
<div class="ae_list sponsorship__guests">
<h2>Guest List</h2>
{#if $slct.sponsorship_obj.guest_li_json && $slct.sponsorship_obj.guest_li_json.length && $slct.sponsorship_obj.guest_li_json[0].full_name}
<ul>
{#each $slct.sponsorship_obj.guest_li_json as guest, index}
<li class="sponsorship__guest"
class:ae_d_none={!$slct.sponsorship_obj.guest_li_json[index].full_name}
>
<span class="ae_label">
<span class="fas fa-user"></span> Contact:
</span>
{$slct.sponsorship_obj.guest_li_json[index].full_name}
{#if $slct.sponsorship_obj.guest_li_json[index].email}
| <a href="mailto:{$slct.sponsorship_obj.guest_li_json[index].email}?Subject={$slct.sponsorship_obj.full_name}">{$slct.sponsorship_obj.guest_li_json[index].email}</a>
{/if}
{#if $slct.sponsorship_obj.guest_li_json[index].phone_mobile}
<span class="ae_label">| Mobile:</span>
<a href="tel:{$slct.sponsorship_obj.guest_li_json[index].phone_mobile}">{$slct.sponsorship_obj.guest_li_json[index].phone_mobile}</a>
{/if}
{#if $slct.sponsorship_obj.guest_li_json[index].phone_home}
<span class="ae_label">| Home:</span>
<a href="tel:{$slct.sponsorship_obj.guest_li_json[index].phone_home}">{$slct.sponsorship_obj.guest_li_json[index].phone_home}</a>
{/if}
{#if $slct.sponsorship_obj.guest_li_json[index].phone_office}
<span class="ae_label">| Office:</span>
<a href="tel:{$slct.sponsorship_obj.guest_li_json[index].phone_office}">{$slct.sponsorship_obj.guest_li_json[index].phone_office}</a>
{/if}
{#if $slct.sponsorship_obj.guest_li_json[index].other_text}| {$slct.sponsorship_obj.guest_li_json[index].other_text}{/if}
</li>
{/each}
</ul>
{:else}
<div class="ae_warning">No guest list found!</div>
{/if}
</div>
<section class="ae_section ae_meta sponsorship__meta">
<div class="ae_group">
<span
class="sponsorship__id"
class:ae_d_none={!$ae_app.administrator_access}>
ID:
{$slct.sponsorship_obj.sponsorship_id_random}
</span>
<span
class="sponsorship__created_on"
>
Created on: {ae.util.iso_datetime_formatter($slct.sponsorship_obj.created_on, 'datetime_short')}
</span>
<span
class="sponsorship__updated_on"
class:ae_d_none={!$slct.sponsorship_obj.updated_on}
>
Updated on: {ae.util.iso_datetime_formatter($slct.sponsorship_obj.updated_on, 'datetime_short')}
</span>
</div>
{#if $ae_app.trusted_access || $slct.sponsorship_obj.external_person_id === $ae_app.novi_uuid || $slct.sponsorship_obj.contact_1_email === $ae_app.novi_email}
<div class="ae_options">
<button
on:click={() => {
// $slct.sponsorship_id = $slct.sponsorship_obj.sponsorship_id_random;
// $slct.sponsorship_obj = $slct.sponsorship_obj;
// const url = new URL(location);
// url.searchParams.set('sponsorship_id', $slct.sponsorship_obj.sponsorship_id_random);
// history.pushState({}, '', url);
// $ae_app.sponsorships.show_main__options = true;
// $ae_app.sponsorships.show_list__sponsorship_obj_li = true;
$ae_app.sponsorships.show_view__sponsorship_obj = false;
$ae_app.sponsorships.show_edit__sponsorship_obj = true;
}}
class="btn btn-xs btn-secondary"
title={`Edit sponsorship: ${$slct.sponsorship_obj.name}`}
>
<span class="fas fa-edit"></span> Edit
</button>
</div>
{/if}
</section>
</div>
</section>
<style>
.ae_label {
font-size: smaller;
}
.ae_value {
font-weight: bold;
}
.sponsorship__user_timezone {
font-size: smaller;
font-style: italic;
}
.sponsorship_obj .ae_meta {
flex-direction: column;
/* justify-content: space-between; */
}
.sponsorship_obj .ae_meta .ae_group {
flex-direction: row;
}
.sponsorship_obj .ae_meta .ae_options {
flex-direction: row;
justify-content: space-between;
}
/* a {
color: #82B6E1;
} */
</style>

View File

@@ -1,47 +0,0 @@
<script lang="ts">
import svelteLogo from './assets/svelte.svg'
import viteLogo from '/vite.svg'
import Counter from './lib/Counter.svelte'
</script>
<main>
<div>
<a href="https://vitejs.dev" target="_blank" rel="noreferrer">
<img src={viteLogo} class="logo" alt="Vite Logo" />
</a>
<a href="https://svelte.dev" target="_blank" rel="noreferrer">
<img src={svelteLogo} class="logo svelte" alt="Svelte Logo" />
</a>
</div>
<h1>Vite + Svelte</h1>
<div class="card">
<Counter />
</div>
<p>
Check out <a href="https://github.com/sveltejs/kit#readme" target="_blank" rel="noreferrer">SvelteKit</a>, the official Svelte app framework powered by Vite!
</p>
<p class="read-the-docs">
Click on the Vite and Svelte logos to learn more
</p>
</main>
<style>
.logo {
height: 6em;
padding: 1.5em;
will-change: filter;
transition: filter 300ms;
}
.logo:hover {
filter: drop-shadow(0 0 2em #646cffaa);
}
.logo.svelte:hover {
filter: drop-shadow(0 0 2em #ff3e00aa);
}
.read-the-docs {
color: #888;
}
</style>

View File

@@ -1,711 +0,0 @@
:root {
font-family: system-ui, Helvetica, Arial, sans-serif;
/* line-height: 1.5; */
/* font-weight: 400; */
color-scheme: light dark;
/* color: rgba(255, 255, 255, 0.87); */
/* background-color: #242424; */
/* font-synthesis: none; */
/* text-rendering: optimizeLegibility; */
/* -webkit-font-smoothing: antialiased; */
/* -moz-osx-font-smoothing: grayscale; */
/* -webkit-text-size-adjust: 100%; */
}
body {
/* Use boarder-box to make things easier with borders and scrolling in general. */
box-sizing: border-box;
/* outline: dashed thick blue; */
/* border: solid thick blue; */
margin: 1em;
padding: 0em;
/* Account for the margin */
height: calc(100vh - 1em - 1em);
/* max-width: 1280px; */
/* background-color: hsla(240, 50%, 20%); */
background-color: hsla(207, 43%, 18%);
/* Display as flex does not seem to work well here. */
}
.svelte_target.ae_svelte_app_hub {
position: fixed;
top: 0;
right: 0;
background-color: hsla(0, 0%, 100%, .50);
color: black;
font-size: x-small;
padding: .25em;
z-index: 1000;
opacity: .5;
transition: all .25s ease-in-out;
}
.svelte_target.ae_svelte_app_hub:hover {
opacity: 1;
background-color: hsla(0, 50%, 80%, .75);
}
.svelte_target.ae_svelte_app {
box-sizing: border-box;
/* box-sizing: content-box; */
/* outline: solid thin hsla(0, 50%, 50%, .50); */
border: solid medium hsla(0, 0%, 50%, .40);
/* border-color: hsla(207, 43%, 18%); */
/* background-color: white; */
/* background-color: hsla(240, 100%, 95%, .97); */
background-color: hsla(0, 0%, 100%, .90);
overflow: scroll;
height: 100%;
/* max-height: calc(100% - 1em); */
/* width: 100%; */
/* max-width: calc(100% - 1em); */
max-width: 1280px;
/* margin: 1em; */
/* Use auto margin to center this element within the body */
margin: auto;
padding: .5em;
}
/* Use this to fix the scrolling. This is mostly useful for wide tables. */
/* This must be applied to the parent of the table. */
.svelte_target.ae_svelte_app .svelte_component {
overflow: scroll;
}
#Site-Header {
background-color: hsla(0, 0%, 100%, 0.85);
padding: .5em 1em;
margin-bottom: 1em;
/* display: flex; */
/* justify-content: space-between; */
}
#Site-Header h1 {
/* text-shadow: 0em 0em .75em hsla(240,100%,25%,1); */
/* text-shadow: 0em 0em .75em hsla(0,0%,5%,1); */
font-size: 2.5em;
line-height: 1.1;
margin: 0;
padding: 0;
}
#Site-Header h2 {
font-size: 1.5em;
line-height: 1.1;
margin: 0;
padding: 0;
/* Make font italic */
font-style: italic;
}
#Site-Nav-Menu {
background-color: hsla(0, 0%, 100%, 0.85);
/* padding: .5em 1em; */
margin-bottom: 1em;
}
#Site-Footer {
background-color: hsla(0, 0%, 100%, 0.85);
padding: .5em 1em;
margin-top: 1em;
display: flex;
justify-content: space-between;
}
address {
margin-bottom: .25em;
padding-left: .5em;
font-style: italic;
}
pre {
white-space: pre-wrap;
word-break: normal;
word-wrap: normal;
border: none;
}
table.ae_table {
/* border-collapse: collapse; */
border-spacing: 0px;
border: solid thin hsla(0, 0%, 0%, .30);
width: 100%;
max-width: 100%;
/* margin: 1em; */
/* padding: 1em; */
/* overflow: scroll; */
}
.ae_table tr {
border: solid thin hsla(0, 0%, 0%, .20);
}
.ae_table th {
border: solid thin hsla(0, 0%, 0%, .10);
border-bottom: solid thin hsla(0, 0%, 0%, .20);
padding: .5em;
/* text-align: center; */
}
.ae_table td {
border: solid thin hsla(0, 0%, 0%, .10);
padding: .5em;
text-align: center;
}
textarea {
/* width: calc(fit-content - 1em); */
width: 100%;
max-width: calc(fit-content - .5em);
}
button.ae_normal, .btn.ae_normal {
/* font: normal 1em sans-serif; */
font-size: 1rem;
}
button.ae_smaller, .btn.ae_smaller {
font-size: .8rem;
}
button.ae_smallest, .btn.ae_smallest {
font-size: .65rem;
}
/* h1 {
font-size: 3.2em;
line-height: 1.1;
} */
/* .card {
padding: 2em;
} */
/* #app {
max-width: 1280px;
margin: 0 auto;
padding: 2rem;
text-align: center;
} */
/* button {
border-radius: 8px;
border: 1px solid transparent;
padding: 0.6em 1.2em;
font-size: 1em;
font-weight: 500;
font-family: inherit;
background-color: #1a1a1a;
cursor: pointer;
transition: border-color 0.25s;
}
button:hover {
border-color: #646cff;
}
button:focus,
button:focus-visible {
outline: 4px auto -webkit-focus-ring-color;
} */
/* @media (prefers-color-scheme: light) {
:root {
color: #213547;
background-color: #ffffff;
}
a:hover {
color: #747bff;
}
button {
background-color: #f9f9f9;
}
} */
/* BEGIN: Novi and Bootstrap specific fixes */
/* .ae_btn .btn_xs, .btn .btn-xs {
font-size: .65rem;
} */
.ae_btn.btn-danger, .ae_btn.btn-info, .ae_btn.btn-warning {
border-radius: 60px;
}
/* END: Novi and Bootstrap specific fixes */
.ae_main {
/* min-height: fit-content; */
/* min-height: 100vh; */
/* height: 100%; */
/* min-width: 100vw; */
/* width: 100%; */
/* contain: layout; */
/* contain: content; */
/* contain: size; */
}
.ae_dev_in_progress {
background-color: hsla(300,80%,50%,1);
}
.c_idaa_bb, .c_idaa_recovery_meetings {
display: flex;
flex-direction: column;
/* align-items: center; */
/* justify-content: center; */
/* min-height: 100vh; */
gap: 1em;
}
.c_idaa_archives>.ae_meta, .c_idaa_bb>.ae_meta, .c_idaa_recovery_meetings>.ae_meta {
background-color: lightgray;
}
.ae_list.archive_obj_li {
/* border: solid thin gray; */
display: flex;
flex-direction: column;
/* align-items: stretch; */
/* justify-content: stretch; */
gap: .5em;
}
.ae_list.archive_obj_li .ae_object.archive_obj, .ae_list.archive_content_obj_li .ae_object.archive_content_obj {
border-top: solid medium hsla(0,0%,90%,1);
/* border-bottom: solid thin hsla(0,0%,90%,1); */
/* margin: 1em .5em; */
padding: .5em .5em;
width: 100%;
/* flex-grow: 1; */
}
.c_idaa_recovery_meetings section.ae_options fieldset {
display: flex;
flex-direction: row;
}
.c_idaa_recovery_meetings section.ae_options fieldset legend {
display: inline;
/* border: none; */
margin: 0;
width: auto;
}
.ae_list.event_obj_li {
/* border: solid thin gray; */
display: flex;
flex-direction: column;
/* align-items: stretch; */
/* justify-content: stretch; */
gap: .5em;
}
.ae_list.event_obj_li .ae_object.event_obj {
border-top: solid medium hsla(0,0%,90%,1);
/* border-bottom: solid thin hsla(0,0%,90%,1); */
/* margin: 1em .5em; */
padding: .5em .5em;
width: 100%;
/* flex-grow: 1; */
}
/* For now this only affects the IDAA Recovery Meetings when viewing a specific meeting. */
.view__event_obj a, .view__event_obj a.ae_link {
/* color: #007bff; */
color: #82B6E1;
/* text-decoration: underline; */
/* background-color: transparent; */
}
.view__event_obj a:hover, .view__event_obj a:focus, .view__event_obj a.ae_link:hover, .view__event_obj a.ae_link:focus {
color: #0056b3;
text-decoration: underline;
/* background-color: transparent; */
/* scale: 1.1; */
}
.svelte_component {
margin: 0em;
padding: 0em;
}
.ae_section {
display: flex;
flex-direction: column;
}
.ae_warning {
color: red;
}
.ae_highlight {
background-color: hsla(60,100%,50%,1);
}
.ae_d_none, .d-none {
display: none;
}
.ae_group {
/* display: flex; */
/* flex-direction: row; */
/* align-items: center; */
/* justify-content: space-between; */
/* justify-content: space-evenly; */
}
.ae_flex {
display: flex;
/* flex-direction: row; */
/* align-items: center; */
/* justify-content: space-between; */
}
.ae_column {
display: flex;
flex-direction: column;
/* align-items: center; */
/* justify-content: space-between; */
justify-content: space-evenly;
}
.ae_row {
display: flex;
flex-direction: row;
align-items: center;
/* justify-content: space-between; */
justify-content: space-evenly;
}
.ae_flex_justify_around {
justify-content: space-around;
}
.ae_text_align_left {
text-align: left;
}
.ae_text_align_center {
text-align: center;
}
.ae_text_align_right {
text-align: right;
}
.ae_width_25 {
width: 25%;
/* max-width: 25%; */
}
.ae_width_30 {
width: 30%;
/* max-width: 30%; */
}
.ae_width_50 {
width: 50%;
/* max-width: 50%; */
}
.ae_width_100 {
width: 100%;
/* max-width: 100%; */
}
.ae_width_md {
min-width: 16em;
width: 16em;
max-width: 16em;
}
.ae_margin_xs {
margin: .25em;
}
.ae_margin_sm {
margin: .5em;
}
.ae_margin_md {
margin: .75em;
}
.ae_margin_lg {
margin: 1.0em;
}
.ae_margin_lg {
margin: 1.25em;
}
.ae_float_right {
float: right;
align-self: flex-end;
}
.ae_options {
padding: 1em;
}
.ae_fade_in {
/* animation: fadein 1s; */
opacity: 1;
/* height: initial; */
/* max-height: 100%; */
/* width: initial; */
/* max-width: 100%; */
transition: opacity, height, width, .25s ease-in;
/* transition: height 1s ease-in; */
/* width: initial; */
/* transition: opacity, height, width 1s ease-in 1s; */
}
.ae_fade_out {
/* animation: fadeout 1s; */
opacity: 0;
height: 0;
max-height: 0;
width: 0;
max-width: 0;
transition: opacity, height, width, .25s ease-out;
}
/* .ae_section.ae_options {
border: solid thin hsla(0,0%,90%,.75); */
/* Display options using flex (row, wrap, space elements equally) */
/* display: flex;
flex-direction: column;
flex-wrap: wrap;
justify-content: center; */
/* justify-content: space-evenly; */
/* align-content: center;
align-items: center;
} */
.ae_section.ae_meta {
font-size: smaller;
color: hsla(0,0%,50%,1);
}
.svelte_component.ae_edit {
/* outline: dashed thin pink; */
border: solid medium hsla(220,100%,50%,.1);
}
.svelte_component.ae_create {
border: solid medium hsla(0,100%,50%,.1);
}
/* This covers the entire viewable area. Essentially a new "body" */
/* element_ae_modal ae_modal_showing_container ae_modal modal_cover_body */
.ae_modal {
position: fixed;
top: 0;
left: 0;
z-index: 1000;
min-height: 100vh;
height: 100%;
/* max-height: 100vh; */
min-width: 100%;
/* width: 100%; */
width: 100vw;
max-width: 100vw;
/* max-width: 1280px; */
/* background-color: hsla(180,75%,90%,.75); */
background-color: hsla(180,0%,90%,.75);
display: flex;
flex-direction: column;
align-items: center;
/* align-items: flex-start; */
/* justify-content: center; */
/* justify-content: flex-start; */
/* contain: layout; */
contain: strict;
/* contain: size; */
/* Margin should stay 0 and padding can be used to create space within the modal for the actual content. */
margin: 0;
padding: 0em;
/* pointer-events: auto; */
}
.ae_modal .modal_content {
z-index: 1001;
position: relative;
box-sizing: content-box;
background-color: white;
/* margin: 1em;
padding: .25em .5em; */
margin: 0em;
padding: 0em;
border: solid thin lightgray;
border-radius: .5em;
/* box-shadow: .5em .5em 1.5em .5em hsla(0, 0%, 0%, .9); */
box-shadow: 0em 0em 1.5em .5em hsla(0, 0%, 0%, .9);
/* min-height: 50vh; */
max-height: calc(100vh - 2em);
/* max-height: fit-content; */
/* min-width: 50vw; */
max-width: calc(100vw - 2em);
/* max-width: 100vw; */
/* scroll-behavior: auto; */
/* overflow: scroll; */
/* overflow: auto; */
/* contain: content; */
/* contain: strict; */
/* overflow: auto; */
display: flex;
flex-direction: column;
align-items: stretch;
}
.ae_modal .modal_header {
background-color: hsla(0,0%,90%,.5);
border-bottom: solid thin lightgray;
margin: 0em;
padding: .25em .25em;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
}
.ae_modal .modal_body {
/* outline: dashed medium pink; */
margin: 0em;
padding: .25em .25em;
/* height: 100vh; */
/* contain: content; */
/* pointer-events: auto; */
overflow: scroll;
/* overflow-x: auto; */
/* overflow-y: scroll; */
}
.ae_modal .modal_footer {
background-color: hsla(0,0%,90%,.5);
border-top: solid thin lightgray;
margin: 0em;
padding: .25em .25em;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
}
/* body.modal_cover_body {
pointer-events: none;
overflow-y: hidden;
height: fit-content;
contain: size;
} */
body.modal_cover_body .ae_modal {
margin: 0em;
padding: 0em;
/* max-width: 100vw; */
align-items: stretch;
}
body.modal_cover_body .ae_modal .modal_content {
/* outline: dashed thin pink; */
border: none;
border-radius: 0;
box-shadow: none;
max-height: calc(100vh - .5em);
max-width: calc(100vw);
}
body.modal_cover_body .ae_modal .modal_body {
/* outline: dashed medium pink; */
}
form {
display: flex;
flex-direction: column;
/* justify-content: flex-start; */
/* align-items: center; */
padding: .75em;
}
form fieldset {
display: flex;
flex-direction: column;
/* justify-content: flex-start; */
/* align-items: center; */
}
/* Make readonly input fields grayed out and hide border*/
form input:read-only {
/* background-color: hsla(0,0%,90%,1); */
border: none;
}

9
src/app.d.ts vendored Normal file
View File

@@ -0,0 +1,9 @@
// See https://kit.svelte.dev/docs/types#app
// for information about these interfaces
// and what to do when importing types
declare namespace App {
// interface Locals {}
// interface PageData {}
// interface Error {}
// interface Platform {}
}

24
src/app.html Normal file
View File

@@ -0,0 +1,24 @@
<!DOCTYPE html>
<html lang="en" class="light">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
<link rel="manifest" href="%sveltekit.assets%/manifest.json">
<meta name="viewport" content="width=device-width" />
<link rel="preconnect" href="https://fonts.gstatic.com">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans:ital,wght@0,400;0,700;1,400;1,700&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Noto+Serif:ital,wght@0,400;0,700;1,400;1,700&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Roboto+Mono:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;1,100;1,200;1,300;1,400;1,500;1,600;1,700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" integrity="sha512-1ycn6IcaQQ40/MKBW2W4Rhis/DbILU74C1vSrLJxCq57o941Ym01SwNsOMqvEBFlcgUa6xLiPY/NS5R+E6ztJQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />
%sveltekit.head%
</head>
<body data-sveltekit-preload-data="hover" data-theme="my-custom-theme">
<div style="display: contents" class="h-full w-full overflow-hidden">%sveltekit.body%</div>
</body>
</html>

371
src/app.postcss Normal file
View File

@@ -0,0 +1,371 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@tailwind variants;
/* There are no more Tailwind layers. */
html,
body {
@apply h-full overflow-hidden;
/* font-family: 'Liberation Sans', sans-serif; */
/* font-family: 'Noto Sans', sans-serif; */
}
/* default theme */
/* @font-face {
font-family: 'Liberation Sans', sans-serif;
font-family: 'Noto Sans', sans-serif;
src: url('/fonts/liberation/LiberationSans-Regular.ttf');
src: url('/fonts/noto/NotoSans-Regular.ttf');
font-display: swap;
} */
/* modern theme */
@font-face {
font-family: 'Quicksand';
src: url('/fonts/Quicksand.ttf');
font-display: swap;
}
/* :root [data-theme='modern'] { */
/* --theme-rounded-base: 20px;
--theme-rounded-container: 4px; */
/* --theme-font-family-base: 'Liberation Sans', sans-serif; */
/* --theme-font-family-heading: 'Liberation Sans', sans-serif; */
/* } */
.card-footer {
border-top: 1px solid hsla(0, 0%, 0%, 0.5);
margin-top: 1em;
padding-top: 1em;
opacity: .5;
}
/* Tailwind: This "fixes" Tailwind's default group button styles that do not seem to allow hidding buttons. */
.btn-group a.hidden, .btn-group button.hidden {
display: none;
}
.ae_d_none {
display: none;
}
/* Allow content to scroll horizontal if too wide */
.ae_h_scrollfix {
max-width: 100%;
overflow-x: auto;
}
/* These helps with the Skeleton Tailwind modal utility. */
.ae_modal_scrollfix {
/* Allow modal content to scroll if it's too long */
overflow-y: auto;
max-height: 96vh;
/* max-height: 99%; */
}
.ae_debug {
/* A darker pink outline */
outline: thin dashed;
outline-color: hsla(0, 100%, 50%, 0.15);
/* A light pink background color */
background-color: hsla(0, 100%, 50%, 0.15);
}
.ae_debug:hover {
/* A darker pink outline */
outline-color: hsla(0, 100%, 50%, 0.50);
/* A light pink background color */
background-color: hsla(0, 100%, 50%, 0.40);
}
/* Deal with being in an iframe */
#appShell #shell-header.iframe {
display: none;
}
#appShell #shell-footer.iframe {
display: none;
}
/* Remove the background from the body in all cases */
/* body[data-theme] { */
/* background: none; */
/* background-image: none; */
/* } */
/* Remove the background from the body if using iframes */
/* body[data-theme]:has(#page.iframe) { */
/* background: none; */
/* background-image: none; */
/* background-image: url('https://static.oneskyit.com/c/CHOW/images/CHOW_2024_yellow_background.png'); */
/* background-size: cover; */
/* } */
main {
/* background: none;
background-color: hsla(0, 0%, 100%, 0.92); */
}
main>section {
background: none;
background-color: hsla(0, 0%, 100%, 0.92);
padding: .5em;
}
/* @media (min-width: 640px) {
main>div, main>section {
padding: 0;
max-width: 100%;
}
} */
/* @media (min-width: 768px) {
main>div, main>section {
padding: 0;
max-width: 100%;
}
} */
.ae_sponsorships {
/* background: none; */
/* background-color: hsla(0, 0%, 100%, 0.92); */
/* background-image: url('https://static.oneskyit.com/c/CHOW/images/CHOW_2024_yellow_background.png'); */
/* background-size: cover; */
}
pre.pre_wrap {
white-space: pre-wrap;
word-break: normal;
word-wrap: normal;
border: none;
max-width: 100%;
overflow-x: auto;
}
input.required {
/* border-right: solid medium var(--color-warning-500); */
/* color: var(--color-warning-500); */
}
input:required {
/* background-color: var(--alert-color-lightest); */
/* border: solid 2px red; */
/* outline: dashed thin var(--alert-color-lighter); */
/* border-right: solid medium var(--alert-color-mid); */
/* border-right: solid medium var(--warning-color-mid); */
/* border-right: solid medium var(--error-color-mid); */
}
/* input:required:hover {
background-color: var(--alert-color-lighter);
border-right: solid thick var(--alert-color-darker);
} */
/* input:required::before {
display: block;
content: '*';
color: var(--warning-color-darker);
top: 5px;
left: 5px;
} */
.input_required::after {
content: '*';
color: rgb(var(--color-error-500) / 0.9);
position: relative;
/* top: 0em; */
left: .25em;
}
/* Make the group a flex row by default */
/* div.btn-group { */
/* display: flex; */
/* gap: 0; */
/* flex-direction: row; */
/* justify-content: space-around; */
/* align-items: center; */
/* margin: 0;
padding: 0; */
/* } */
/* Make all button elements except for the the first button element not rounded on the left. */
/* Make all button elements except for the fhe last button element not rounded on the right. */
/* These helps with the Skeleton (Tailwind?) button group element. */
.btn-group button {
border-radius: 0;
border: none;
}
/* .md:btn-group button,
.lg:btn-group button {
border-radius: 0;
border: none;
} */
/* div.btn-group button:first-child {
border-top-left-radius: .25rem;
border-bottom-left-radius: .25rem;
}
div.btn-group button:last-child {
border-top-right-radius: .25rem;
border-bottom-right-radius: .25rem;
} */
.ae_obj_prop .label {
}
.ae_obj_prop .value {
font-weight: bold;
}
.ae_md_hide {
/* outline: medium dashed green; */
/* display: none; */
}
@media (max-width: 767px) {
.ae_md_hide {
/* outline: medium dashed red; */
display: none;
}
}
@media (min-width: 768px) {
.ae_lg_hide {
/* outline: medium dashed blue; */
display: none;
}
}
/* 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: 98%;
min-width: 98%;
}
section.ae_quick_popover_small {
position: fixed;
top: 1em;
left: 50%;
transform: translate(-50%, 0%);
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: 24rem;
max-height: 95%;
min-width: 50%;
max-width: 95%;
}
.fade_50 {
opacity: 0.5;
}
.fade_50:hover {
opacity: 1;
}
.auth_view_only {
display: none;
}
.ae_root--auth_access .auth_view_only {
display: initial;
}
img.qr_code {
/* outline: solid thin hsla(30, 100%, 50%, .1); */
/* width: 1.50in; */
}
img.qr_code:hover {
/* outline: solid thin green; */
/* width: 2.50in; */
}
img.qr_code:focus {
/* outline: solid thin red; */
/* width: 2.50in; */
}
.dim {
opacity: 0.5;
color: hsla(0, 0%, 50%, .95);
}
.dim_warning {
opacity: 0.5;
/* color: hsla(0, 100%, 50%, .95); */
/* background should be hash marks */
background-image: repeating-linear-gradient(-45deg, hsla(0, 100%, 50%, .25), hsla(0, 100%, 50%, .25) 10px, transparent 10px, transparent 20px);
}
@media (max-width: 767px) {
.sk_header.hide_sm {
display: none;
}
.sk_header.show_sm {
display: initial;
}
.sk_header.show_md {
display: none;
}
}
@media (min-width: 768px) {
.sk_header.hide_md {
display: none;
}
.sk_header.show_md {
display: initial;
}
.sk_header.show_sm {
display: none;
}
}

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="26.6" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 308"><path fill="#FF3E00" d="M239.682 40.707C211.113-.182 154.69-12.301 113.895 13.69L42.247 59.356a82.198 82.198 0 0 0-37.135 55.056a86.566 86.566 0 0 0 8.536 55.576a82.425 82.425 0 0 0-12.296 30.719a87.596 87.596 0 0 0 14.964 66.244c28.574 40.893 84.997 53.007 125.787 27.016l71.648-45.664a82.182 82.182 0 0 0 37.135-55.057a86.601 86.601 0 0 0-8.53-55.577a82.409 82.409 0 0 0 12.29-30.718a87.573 87.573 0 0 0-14.963-66.244"></path><path fill="#FFF" d="M106.889 270.841c-23.102 6.007-47.497-3.036-61.103-22.648a52.685 52.685 0 0 1-9.003-39.85a49.978 49.978 0 0 1 1.713-6.693l1.35-4.115l3.671 2.697a92.447 92.447 0 0 0 28.036 14.007l2.663.808l-.245 2.659a16.067 16.067 0 0 0 2.89 10.656a17.143 17.143 0 0 0 18.397 6.828a15.786 15.786 0 0 0 4.403-1.935l71.67-45.672a14.922 14.922 0 0 0 6.734-9.977a15.923 15.923 0 0 0-2.713-12.011a17.156 17.156 0 0 0-18.404-6.832a15.78 15.78 0 0 0-4.396 1.933l-27.35 17.434a52.298 52.298 0 0 1-14.553 6.391c-23.101 6.007-47.497-3.036-61.101-22.649a52.681 52.681 0 0 1-9.004-39.849a49.428 49.428 0 0 1 22.34-33.114l71.664-45.677a52.218 52.218 0 0 1 14.563-6.398c23.101-6.007 47.497 3.036 61.101 22.648a52.685 52.685 0 0 1 9.004 39.85a50.559 50.559 0 0 1-1.713 6.692l-1.35 4.116l-3.67-2.693a92.373 92.373 0 0 0-28.037-14.013l-2.664-.809l.246-2.658a16.099 16.099 0 0 0-2.89-10.656a17.143 17.143 0 0 0-18.398-6.828a15.786 15.786 0 0 0-4.402 1.935l-71.67 45.674a14.898 14.898 0 0 0-6.73 9.975a15.9 15.9 0 0 0 2.709 12.012a17.156 17.156 0 0 0 18.404 6.832a15.841 15.841 0 0 0 4.402-1.935l27.345-17.427a52.147 52.147 0 0 1 14.552-6.397c23.101-6.006 47.497 3.037 61.102 22.65a52.681 52.681 0 0 1 9.003 39.848a49.453 49.453 0 0 1-22.34 33.12l-71.664 45.673a52.218 52.218 0 0 1-14.563 6.398"></path></svg>

Before

Width:  |  Height:  |  Size: 1.9 KiB

7
src/index.test.ts Normal file
View File

@@ -0,0 +1,7 @@
import { describe, it, expect } from 'vitest';
describe('sum test', () => {
it('adds 1 + 2 to equal 3', () => {
expect(1 + 2).toBe(3);
});
});

View File

@@ -1,10 +0,0 @@
<script lang="ts">
let count: number = 0
const increment = () => {
count += 1
}
</script>
<button on:click={increment}>
count is {count}
</button>

View File

@@ -0,0 +1,63 @@
import axios from 'axios';
// Updated 2024-05-23
export let delete_object = async function delete_object(
{
api_cfg=null,
endpoint='',
params={},
data={},
return_meta=false,
log_lvl=0
}: {
api_cfg: any,
endpoint: string,
params?: any,
data?: any,
return_meta?: boolean,
log_lvl?: number
}
) {
console.log('*** delete_object() ***');
if (log_lvl) {
// console.log(api_cfg);
console.log(endpoint);
console.log(params);
if (log_lvl > 1) {
console.log('Data:', data);
console.log(typeof data);
}
// console.log(return_meta);
// console.log(as_list);
}
// https://stackoverflow.com/questions/51069552/axios-delete-request-with-body-and-headers
let axios_api = axios.create({
baseURL: api_cfg['base_url'],
// timeout: 2000,
/* other custom settings */
});
axios_api.defaults.headers = api_cfg['headers'];
//OLD: axios_api.delete(endpoint, { 'data': data })
let response_data = await axios_api.delete(endpoint, { params: params, 'data': data })
.then(function (response) {
console.log(response.data);
return response.data;
})
.catch(function (error) {
if (error.response && error.response.status === 404) {
return null; // Returning null since there were no results
}
console.log(error);
return false; // Returning false since something may have gone wrong. Also more in line with what the API returns.
// return error;
});
if (log_lvl > 1) {
console.log(response_data);
}
return response_data;
}

View File

@@ -0,0 +1,172 @@
import type { key_val } from '$lib/ae_stores';
import { get_object } from './api_get_object';
// Updated 2023-12-01
export async function get_ae_obj_id_crud(
{
api_cfg,
no_account_id = false,
obj_type,
obj_id,
use_alt_table = false,
use_alt_base = false,
inc = {},
enabled = 'enabled',
hidden = 'not_hidden',
limit = 999999,
offset = 0,
data = {},
// key,
// jwt = null,
headers = {},
params = {},
timeout = 25000,
return_meta = false,
log_lvl = 0
}: {
api_cfg: any,
no_account_id?: boolean,
obj_type: string,
obj_id: string,
use_alt_table?: boolean,
use_alt_base?: boolean,
inc?: any,
enabled?: string,
hidden?: string,
limit?: number,
offset?: number,
data?: any,
// key: string,
// jwt?: string,
headers?: any,
params?: key_val,
timeout?: number,
return_meta?: boolean,
log_lvl?: number
}
) {
if (log_lvl) {
console.log('*** get_ae_obj_id_crud() ***');
}
// data = {};
// data['super_key'] = key;
// data['jwt'] = jwt;
// NOTE: The key and or JWT should be in the header of the DELETE, GET, PATCH, POST
let endpoint = '';
if (obj_type == 'account') {
endpoint = `/crud/account/${obj_id}`;
} else if (obj_type == 'address') {
endpoint = `/crud/address/${obj_id}`;
} else if (obj_type == 'archive') {
endpoint = `/crud/archive/${obj_id}`;
} else if (obj_type == 'archive_content') {
endpoint = `/crud/archive/content/${obj_id}`;
} else if (obj_type == 'contact') {
endpoint = `/crud/contact/${obj_id}`;
} else if (obj_type == 'data_store') {
endpoint = `/crud/data_store/${obj_id}`;
} else if (obj_type == 'event') {
endpoint = `/crud/event/${obj_id}`;
} else if (obj_type == 'event_abstract') {
endpoint = `/crud/event/abstract/${obj_id}`;
} else if (obj_type == 'event_badge') {
endpoint = `/crud/event/badge/${obj_id}`;
} else if (obj_type == 'event_device') {
endpoint = `/crud/event/device/${obj_id}`;
} else if (obj_type == 'event_exhibit') {
endpoint = `/crud/event/exhibit/${obj_id}`;
} else if (obj_type == 'event_exhibit_tracking') {
endpoint = `/crud/event/exhibit/tracking/${obj_id}`;
} else if (obj_type == 'event_file') {
endpoint = `/crud/event/file/${obj_id}`;
} else if (obj_type == 'event_location') {
endpoint = `/crud/event/location/${obj_id}`;
} else if (obj_type == 'event_person') {
endpoint = `/crud/event/person/${obj_id}`;
} else if (obj_type == 'event_presentation') {
endpoint = `/crud/event/presentation/${obj_id}`;
} else if (obj_type == 'event_presenter') {
endpoint = `/crud/event/presenter/${obj_id}`;
} else if (obj_type == 'event_session') {
endpoint = `/crud/event/session/${obj_id}`;
} else if (obj_type == 'event_track') {
endpoint = `/crud/event/track/${obj_id}`;
} else if (obj_type == 'grant') {
endpoint = `/crud/grant/${obj_id}`;
} else if (obj_type == 'hosted_file') {
endpoint = `/crud/hosted_file/${obj_id}`;
} else if (obj_type == 'journal') {
endpoint = `/crud/journal/${obj_id}`;
} else if (obj_type == 'journal_entry') {
endpoint = `/crud/journal/entry/${obj_id}`;
} else if (obj_type == 'order') {
endpoint = `/crud/order/${obj_id}`;
} else if (obj_type == 'order_line') {
endpoint = `/crud/order/line/${obj_id}`;
} else if (obj_type == 'page') {
endpoint = `/crud/page/${obj_id}`;
} else if (obj_type == 'person') {
endpoint = `/crud/person/${obj_id}`;
} else if (obj_type == 'post') {
endpoint = `/crud/post/${obj_id}`;
} else if (obj_type == 'post_comment') {
endpoint = `/crud/post/comment/${obj_id}`;
} else if (obj_type == 'site') {
endpoint = `/crud/site/${obj_id}`;
} else if (obj_type == 'site_domain') {
endpoint = `/crud/site/domain/${obj_id}`;
} else if (obj_type == 'sponsorship_cfg') {
endpoint = `/crud/sponsorship/cfg/${obj_id}`;
} else if (obj_type == 'sponsorship') {
endpoint = `/crud/sponsorship/${obj_id}`;
// } else if (obj_type == 'user') {
// endpoint = `/crud/user/${obj_id}`;
} else {
console.log(`Unknown object type: ${obj_type}`);
return false;
}
if (log_lvl) {
console.log('Endpoint:', endpoint);
}
params['use_alt_table'] = use_alt_table;
params['use_alt_base'] = use_alt_base;
if (log_lvl) {
console.log('Params:', params);
}
if (no_account_id) {
headers['x-no-account-id'] = 'Nothing to See Here';
delete headers['x-account-id'];
delete api_cfg['headers']['x-account-id'];
// headers['x-account-id'] = null;
// headers['x-account-id'] = '_XY7DXtc9Mxx';
// params['x_no_account_id_token'] = 'Nothing to See Here';
// Remove the x-account-id header
// if (headers['x-account-id']) {
// delete headers['x-account-id'];
// }
// headers['x-account-id'] = null;
// headers['x-no-account-id-token'] = 'Nothing to See Here'; // get_object() will fix the underscores to dashes
}
let object_obj_get_promise = await get_object({
api_cfg: api_cfg,
endpoint: endpoint,
headers: headers,
params: params,
timeout: timeout,
log_lvl: log_lvl
});
if (log_lvl > 1) {
console.log(object_obj_get_promise);
}
return object_obj_get_promise;
}

View File

@@ -0,0 +1,229 @@
import type { key_val } from '$lib/ae_stores';
import { get_object } from './api_get_object';
// The lookup "obj_type" should broken out into a separate function. - 2024-08-07
// Updated 2023-11-15
export async function get_ae_obj_li_for_obj_id_crud(
{
api_cfg,
obj_type,
for_obj_type,
for_obj_id, // NOTE: Changed 2023-12-06 to no longer required
use_alt_table=false,
use_alt_base=false,
inc={},
enabled='enabled',
hidden='not_hidden',
order_by_li=null,
limit=999999,
offset=0,
// key,
// jwt=null,
headers={},
params_json=null, // NOTE: This is a JSON object that needs to be safely converted to a string for the params. This is used for the API endpoint. Example: { "fulltext_search": { "default_qry_str": "Search string for default", "address_default_qry_str": "Search string for address", "contact_1_default_qry_str": "Search string for contact_1" } }
// json_obj=null, // NOTE: This is a JSON object that needs to be safely converted to a string for the params. This is used for the search endpoint.
params={},
return_meta=false,
log_lvl=1
}: {
api_cfg: any,
obj_type: string,
for_obj_type: string,
for_obj_id?: string,
use_alt_table?: boolean,
use_alt_base?: boolean,
inc?: key_val
enabled?: string,
hidden?: string,
order_by_li?: any,
limit?: number,
offset?: number,
// key: string,
// jwt?: string,
headers?: any,
params_json?: any,
// json_obj?: any,
params?: key_val,
return_meta?: boolean,
log_lvl?: number
}
) {
if (log_lvl) {
console.log('*** get_ae_obj_li_for_obj_id_crud() ***');
}
// data = {};
// data['super_key'] = key;
// data['jwt'] = jwt;
// NOTE: The key and or JWT should be in the header of the DELETE, GET, PATCH, POST
// const endpoint = `/crud/${obj_type}/list`;
let endpoint = '';
if (obj_type == 'account') {
endpoint = `/crud/account/list`;
} else if (obj_type == 'address') {
endpoint = `/crud/address/list`;
} else if (obj_type == 'archive') {
endpoint = `/crud/archive/list`;
} else if (obj_type == 'archive_content') {
endpoint = `/crud/archive/content/list`;
} else if (obj_type == 'contact') {
endpoint = `/crud/contact/list`;
} else if (obj_type == 'data_store') {
endpoint = `/crud/data_store/list`;
} else if (obj_type == 'event') {
endpoint = `/crud/event/list`;
} else if (obj_type == 'event_abstract') {
endpoint = `/crud/event/abstract/list`;
} else if (obj_type == 'event_badge') {
endpoint = `/crud/event/badge/list`;
} else if (obj_type == 'event_device') {
endpoint = `/crud/event/device/list`;
} else if (obj_type == 'event_exhibit') {
endpoint = `/crud/event/exhibit/list`;
} else if (obj_type == 'event_exhibit_tracking') {
endpoint = `/crud/event/exhibit/tracking/list`;
} else if (obj_type == 'event_file') {
endpoint = `/crud/event/file/list`;
} else if (obj_type == 'event_location') {
endpoint = `/crud/event/location/list`;
} else if (obj_type == 'event_person') {
endpoint = `/crud/event/person/list`;
} else if (obj_type == 'event_presentation') {
endpoint = `/crud/event/presentation/list`;
} else if (obj_type == 'event_presenter') {
endpoint = `/crud/event/presenter/list`;
} else if (obj_type == 'event_session') {
endpoint = `/crud/event/session/list`;
} else if (obj_type == 'event_track') {
endpoint = `/crud/event/track/list`;
} else if (obj_type == 'grant') {
endpoint = `/crud/grant/list`;
} else if (obj_type == 'hosted_file') {
endpoint = `/crud/hosted_file/list`;
} else if (obj_type == 'journal') {
endpoint = `/crud/journal/list`;
} else if (obj_type == 'journal_entry') {
endpoint = `/crud/journal/entry/list`;
} else if (obj_type == 'order') {
endpoint = `/crud/order/list`;
} else if (obj_type == 'order_line') {
endpoint = `/crud/order/line/list`;
} else if (obj_type == 'page') {
endpoint = `/crud/page/list`;
} else if (obj_type == 'person') {
endpoint = `/crud/person/list`;
} else if (obj_type == 'post') {
endpoint = `/crud/post/list`;
} else if (obj_type == 'post_comment') {
endpoint = `/crud/post/comment/list`;
} else if (obj_type == 'site') {
endpoint = `/crud/site/list`;
} else if (obj_type == 'sponsorship_cfg') {
endpoint = `/crud/sponsorship/cfg/list`;
} else if (obj_type == 'sponsorship') {
endpoint = `/crud/sponsorship/list`;
// } else if (obj_type == 'user') {
// endpoint = `/crud/user/list`;
// } else if (obj_type == 'lu' && for_obj_type == 'country_subdivision') {
// endpoint = `/crud/lu/country_subdivision/list`;
// for_obj_type = null;
// } else if (obj_type == 'lu' && for_obj_type == 'country') {
// endpoint = `/crud/lu/country/list`;
// for_obj_type = null;
// } else if (obj_type == 'lu' && for_obj_type == 'time_zone') {
// endpoint = `/crud/lu/time_zone/list`;
// for_obj_type = null;
} else {
console.log(`Unknown object type: ${obj_type}`);
return false;
}
if (log_lvl) {
console.log('Endpoint:', endpoint);
}
if (for_obj_type) {
params['for_obj_type'] = for_obj_type;
}
if (for_obj_id) {
params['for_obj_id'] = for_obj_id;
}
params['use_alt_table'] = use_alt_table;
params['use_alt_base'] = use_alt_base;
/* Need to deal with inc params here */
let allowed_enabled_list = ['all', 'enabled', 'not_enabled']
if (allowed_enabled_list.includes(enabled) ) {
params['enabled'] = enabled;
}
let allowed_hidden_list = ['all', 'hidden', 'not_hidden'];
if (allowed_hidden_list.includes(hidden) ) {
params['hidden'] = hidden;
}
// NOTE: The order_by_li variable is in the "headers" because if is a the URL GET params do not handle multiple values very well. Maybe base64 encore in the future or something? Reminder that GET requests should not have a body (no JSON).
// NOTE: The order_by_li should be a key value pair of the property/DB field to sort and how to sort (ASC or DESC)
if (order_by_li) {
if (log_lvl) {
console.log('Order By:', order_by_li);
}
headers['order_by_li'] = order_by_li;
}
if (limit >= 0) {
params['limit'] = limit;
}
if (offset >= 0) {
params['offset'] = offset;
}
if (params_json) {
// NOTE: This is a JSON object that needs to be safely converted to a string for the params. This is used for the search endpoint.
// Max characters for a GET request is 2083. This is a limitation of the browser (Microsoft IE and Edge).
if (log_lvl) {
console.log('JSON Object:', params_json);
console.log(JSON.stringify(params_json));
}
// NOTE: "jp" stands for "JSON Params"
params['jp'] = encodeURIComponent(JSON.stringify(params_json));
if (params['jp'].length > 2083) {
console.log(`The JSON object is too large to be used as a GET parameter. The overall max URL length is 2083 characters. Please use the POST endpoint instead. Length = ${params['jp'].length} [THIS DOES NOT EXIST YET]`);
return false;
}
}
// if (json_obj) {
// // NOTE: This is a JSON object that needs to be safely converted to a string for the params. This is used for the search endpoint.
// // Max characters for a GET request is 2083. This is a limitation of the browser (Microsoft IE and Edge).
// console.log('JSON Object:', json_obj);
// params['json_str'] = encodeURIComponent(JSON.stringify(json_obj));
// if (params['json_str'].length > 2083) {
// console.log(`The JSON object is too large to be used as a GET parameter. The overall max URL length is 2083 characters. Please use the POST endpoint instead. Length = ${params['json_str'].length} [THIS DOES NOT EXIST YET]`);
// return false;
// }
// }
if (log_lvl) {
console.log('Params:', params);
}
let object_li_get_promise = await get_object({
api_cfg: api_cfg,
endpoint: endpoint,
headers: headers,
params: params,
return_meta: return_meta,
log_lvl: log_lvl
});
if (log_lvl > 1) {
console.log(object_li_get_promise);
}
return object_li_get_promise;
}

View File

@@ -0,0 +1,236 @@
import type { key_val } from '$lib/ae_stores';
import { get_object } from './api_get_object';
// The lookup "obj_type" should broken out into a separate function. - 2024-08-07
// Updated 2023-11-15
export async function get_ae_obj_li_for_obj_id_crud_v2(
{
api_cfg,
obj_type,
for_obj_type,
for_obj_id, // NOTE: Changed 2023-12-06 to no longer required
use_alt_tbl = false, // Alternate table or view name
use_alt_mdl = false, // Alternate model name
use_alt_exp = false, // Alternate export table or view name
inc = {},
enabled = 'enabled',
hidden = 'not_hidden',
order_by_li = null,
limit = 999999,
offset = 0,
// key,
// jwt = null,
headers = {},
params_json = null, // NOTE: This is a JSON object that needs to be safely converted to a string for the params. This is used for the API endpoint. Example: { "fulltext_search": { "default_qry_str": "Search string for default", "address_default_qry_str": "Search string for address", "contact_1_default_qry_str": "Search string for contact_1" } }
// json_obj = null, // NOTE: This is a JSON object that needs to be safely converted to a string for the params. This is used for the search endpoint.
params = {},
return_meta = false,
log_lvl = 1
}: {
api_cfg: any,
obj_type: string,
for_obj_type: string,
for_obj_id?: string,
use_alt_tbl?: boolean|string,
use_alt_mdl?: boolean|string,
use_alt_exp?: boolean|string,
inc?: key_val
enabled?: string,
hidden?: string,
order_by_li?: any,
limit?: number,
offset?: number,
// key: string,
// jwt?: string,
headers?: any,
params_json?: any,
// json_obj?: any,
params?: key_val,
return_meta?: boolean,
log_lvl?: number
}
) {
if (log_lvl) {
console.log('*** get_ae_obj_li_for_obj_id_crud() ***');
}
// data = {};
// data['super_key'] = key;
// data['jwt'] = jwt;
// NOTE: The key and or JWT should be in the header of the DELETE, GET, PATCH, POST
// const endpoint = `/crud/${obj_type}/list`;
let endpoint = '';
if (obj_type == 'account') {
endpoint = `/crud/account/list`;
} else if (obj_type == 'address') {
endpoint = `/crud/address/list`;
} else if (obj_type == 'archive') {
endpoint = `/crud/archive/list`;
} else if (obj_type == 'archive_content') {
endpoint = `/crud/archive/content/list`;
} else if (obj_type == 'contact') {
endpoint = `/crud/contact/list`;
} else if (obj_type == 'data_store') {
endpoint = `/crud/data_store/list`;
} else if (obj_type == 'event') {
endpoint = `/crud/event/list`;
} else if (obj_type == 'event_abstract') {
endpoint = `/crud/event/abstract/list`;
} else if (obj_type == 'event_badge') {
endpoint = `/crud/event/badge/list`;
} else if (obj_type == 'event_device') {
endpoint = `/crud/event/device/list`;
} else if (obj_type == 'event_exhibit') {
endpoint = `/crud/event/exhibit/list`;
} else if (obj_type == 'event_exhibit_tracking') {
endpoint = `/crud/event/exhibit/tracking/list`;
} else if (obj_type == 'event_file') {
endpoint = `/crud/event/file/list`;
} else if (obj_type == 'event_location') {
endpoint = `/crud/event/location/list`;
} else if (obj_type == 'event_person') {
endpoint = `/crud/event/person/list`;
} else if (obj_type == 'event_presentation') {
endpoint = `/crud/event/presentation/list`;
} else if (obj_type == 'event_presenter') {
endpoint = `/crud/event/presenter/list`;
} else if (obj_type == 'event_session') {
endpoint = `/crud/event/session/list`;
} else if (obj_type == 'event_track') {
endpoint = `/crud/event/track/list`;
} else if (obj_type == 'grant') {
endpoint = `/crud/grant/list`;
} else if (obj_type == 'hosted_file') {
endpoint = `/crud/hosted_file/list`;
} else if (obj_type == 'journal') {
endpoint = `/crud/journal/list`;
} else if (obj_type == 'journal_entry') {
endpoint = `/crud/journal/entry/list`;
} else if (obj_type == 'order') {
endpoint = `/crud/order/list`;
} else if (obj_type == 'order_line') {
endpoint = `/crud/order/line/list`;
} else if (obj_type == 'page') {
endpoint = `/crud/page/list`;
} else if (obj_type == 'person') {
endpoint = `/crud/person/list`;
} else if (obj_type == 'post') {
endpoint = `/crud/post/list`;
} else if (obj_type == 'post_comment') {
endpoint = `/crud/post/comment/list`;
} else if (obj_type == 'site') {
endpoint = `/crud/site/list`;
} else if (obj_type == 'sponsorship_cfg') {
endpoint = `/crud/sponsorship/cfg/list`;
} else if (obj_type == 'sponsorship') {
endpoint = `/crud/sponsorship/list`;
// } else if (obj_type == 'user') {
// endpoint = `/crud/user/list`;
// } else if (obj_type == 'lu' && for_obj_type == 'country_subdivision') {
// endpoint = `/crud/lu/country_subdivision/list`;
// for_obj_type = null;
// } else if (obj_type == 'lu' && for_obj_type == 'country') {
// endpoint = `/crud/lu/country/list`;
// for_obj_type = null;
// } else if (obj_type == 'lu' && for_obj_type == 'time_zone') {
// endpoint = `/crud/lu/time_zone/list`;
// for_obj_type = null;
} else {
console.log(`Unknown object type: ${obj_type}`);
return false;
}
endpoint = `/v2${endpoint}`;
if (log_lvl) {
console.log('Endpoint:', endpoint);
}
if (for_obj_type) {
params['for_obj_type'] = for_obj_type;
}
if (for_obj_id) {
params['for_obj_id'] = for_obj_id;
}
if (use_alt_tbl === true) {
params['tbl_alt'] = 'alt'; // Use alternate table or view name
}
if (use_alt_mdl === true) {
params['mdl_alt'] = 'alt'; // Use alternate model name
}
if (use_alt_exp === true) {
params['exp_alt'] = 'alt'; // Use alternate export table or view name
}
/* Need to deal with inc params here */
let allowed_enabled_list = ['all', 'enabled', 'not_enabled']
if (allowed_enabled_list.includes(enabled) ) {
params['enabled'] = enabled;
}
let allowed_hidden_list = ['all', 'hidden', 'not_hidden'];
if (allowed_hidden_list.includes(hidden) ) {
params['hidden'] = hidden;
}
// NOTE: The order_by_li variable is in the "headers" because if is a the URL GET params do not handle multiple values very well. Maybe base64 encore in the future or something? Reminder that GET requests should not have a body (no JSON).
// NOTE: The order_by_li should be a key value pair of the property/DB field to sort and how to sort (ASC or DESC)
if (order_by_li) {
headers['order_by_li'] = order_by_li;
}
if (limit >= 0) {
params['limit'] = limit;
}
if (offset >= 0) {
params['offset'] = offset;
}
if (params_json) {
// NOTE: This is a JSON object that needs to be safely converted to a string for the params. This is used for the search endpoint.
// Max characters for a GET request is 2083. This is a limitation of the browser (Microsoft IE and Edge).
if (log_lvl) {
console.log('JSON Object:', params_json);
console.log(JSON.stringify(params_json));
}
// NOTE: "jp" stands for "JSON Params"
params['jp'] = encodeURIComponent(JSON.stringify(params_json));
if (params['jp'].length > 2083) {
console.log(`The JSON object is too large to be used as a GET parameter. The overall max URL length is 2083 characters. Please use the POST endpoint instead. Length = ${params['jp'].length} [THIS DOES NOT EXIST YET]`);
return false;
}
}
// if (json_obj) {
// // NOTE: This is a JSON object that needs to be safely converted to a string for the params. This is used for the search endpoint.
// // Max characters for a GET request is 2083. This is a limitation of the browser (Microsoft IE and Edge).
// console.log('JSON Object:', json_obj);
// params['json_str'] = encodeURIComponent(JSON.stringify(json_obj));
// if (params['json_str'].length > 2083) {
// console.log(`The JSON object is too large to be used as a GET parameter. The overall max URL length is 2083 characters. Please use the POST endpoint instead. Length = ${params['json_str'].length} [THIS DOES NOT EXIST YET]`);
// return false;
// }
// }
if (log_lvl) {
console.log('Params:', params);
}
let object_li_get_promise = await get_object({
api_cfg: api_cfg,
endpoint: endpoint,
headers: headers,
params: params,
return_meta: return_meta,
log_lvl: log_lvl
});
if (log_lvl > 1) {
console.log(object_li_get_promise);
}
return object_li_get_promise;
}

View File

@@ -0,0 +1,496 @@
import axios from 'axios';
import type { key_val } from '$lib/ae_stores';
export let temp_get_blob_percent_completed = 0;
// export let get_blob_percent_completed = readable(temp_get_blob_percent_completed);
export let get_blob_percent_completed = temp_get_blob_percent_completed;
export let temp_get_object_percent_completed = 0;
// export let get_object_percent_completed = readable(temp_get_object_percent_completed);
export let get_object_percent_completed = temp_get_object_percent_completed;
// Updated 2024-05-23
export let get_object = async function get_object(
{
api_cfg=null,
endpoint='',
headers={},
params={},
data={},
timeout=60000,
return_meta=false,
return_blob=false,
filename='',
auto_download=false,
as_list=false,
// The task_id value should be a random string that is unique to the task. This is used to identify the task in the message event.
task_id=crypto.randomUUID(),
log_lvl=0
}: {
api_cfg: any,
endpoint: string,
headers?: any,
params?: any,
data?: any,
timeout?: number,
return_meta?: boolean,
return_blob?: boolean,
filename?: null|string,
auto_download?: boolean,
as_list?: boolean,
task_id?: string,
log_lvl?: number
}
) {
if (log_lvl) {
console.log(`*** get_object() *** Endpoint: ${endpoint} AE Task ID: ${task_id}`);
console.log('Params:', params);
if (log_lvl > 1) {
console.log('Data:', data);
console.log(`Base URL: ${api_cfg['base_url']}; Timeout: ${timeout}`);
console.log('API Config:', api_cfg);
}
if (log_lvl > 2) {
console.log(`Return Meta: ${return_meta}; Return Blob: ${return_blob}; Filename: ${filename}; Auto Download: ${auto_download}`);
}
}
if (!api_cfg) {
console.log('No API Config was provided. Returning false.');
return false;
}
let axios_api = axios.create({
baseURL: api_cfg['base_url'],
timeout: timeout, // in milliseconds; 60000 = 60 seconds
/* other custom settings */
});
axios_api.defaults.headers = api_cfg['headers'];
if (log_lvl) {
console.log('axios_api.defaults.headers:', axios_api.defaults.headers);
console.log('Additional headers:', headers);
}
// console.log('Clean the headers. No _underscores_!')
let headers_cleaned: key_val = {};
for (const prop in headers) {
// No underscores allowed in the header parameters!
let prop_cleaned = prop.replaceAll('_', '-');
// The value must be a string for the header!
if (typeof headers[prop] != 'string') {
headers[prop] = JSON.stringify(headers[prop]);
}
headers_cleaned[prop_cleaned] = headers[prop];
if (log_lvl) {
console.log(`${prop_cleaned}: ${headers_cleaned[prop_cleaned]}`);
}
}
headers = headers_cleaned;
if (log_lvl) {
console.log('All headers cleaned:', headers);
}
if (log_lvl) {
console.log('URL params:');
}
for (const prop in params) {
if (log_lvl > 1) {
console.log(`URL param: ${prop}: ${params[prop]}`);
}
if (params[prop] === null ) {
params[prop] = 'null';
}
}
// Handle the case where there is no Blob expected to be returned. Mainly JSON and text data.
if (!return_blob) {
let response_data_promise = await axios_api.get(
endpoint,
{
headers: headers,
params: params,
onDownloadProgress: (progressEvent) => {
let percent_completed = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
);
if (log_lvl > 1) {
console.log('GET Data Progress:', progressEvent.progress, 'Total:', progressEvent.total, 'Loaded:', progressEvent.loaded, 'Percent Completed', percent_completed);
}
temp_get_object_percent_completed = percent_completed;
// WARNING: This needs to be tied to an object type and ID. This is a temporary solution.
try {
// Check if window is defined. This is to prevent errors in SvelteKit.
if (typeof window !== 'undefined') {
window.postMessage({
type: 'api_download_data',
status: 'downloading',
task_id: task_id,
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);
}
}
}
)
.then(function (response) {
if (log_lvl) {
console.log(`GET Response: status=${response.status} statusText=${response.statusText} baseURL=${response.config.baseURL} url=${response.config.url} method=${response.config.method} headers=${response.config.headers} params=${JSON.stringify(response.config.params)}`);
}
if (log_lvl > 1) {
console.log('GET Response:', response);
}
// Post file download message
try {
if (typeof window !== 'undefined') {
window.postMessage({
type: 'api_download_data',
status: 'complete',
task_id: task_id,
endpoint: endpoint,
filename: filename,
size_total: 0,
size_loaded: 0,
percent_completed: 100,
},
'*'
);
}
} catch (error) {
console.log('Error posting message to window:', error);
}
if (!Array.isArray(response.data['data']) && as_list) {
if (log_lvl) {
console.log('Data result is a dictionary/object, not an array/list. Forcing return as an array/list');
}
let return_data = [];
return_data.push(response.data['data']);
return return_data;
} else if (response.data['data']) {
let return_data = response.data['data'];
if (log_lvl) {
if (Array.isArray(return_data)) {
console.log(`Data result is an array/list. Array length: ${return_data.length}`);
} else {
console.log(`Data result is a dictionary/object, not an array/list.`);
}
}
return return_data;
} else {
let return_data = response.data;
if (log_lvl) {
if (Array.isArray(return_data)) {
console.log(`Not a standard response from Aether's API. Data result is an array/list. Array length: ${return_data.length}`);
} else {
console.log(`Not a standard response from Aether's API. Data result is a dictionary/object, not an array/list.`);
}
}
return return_data;
}
})
.catch(function (error) {
// Handle the common and expected 404 "error" first
if (error.response && error.response.status === 404) {
if (log_lvl) {
console.log('The response was a 404 not found "error". Returning null.');
}
if (log_lvl > 1) {
console.log(error.response);
}
if (log_lvl > 2) {
console.log(error);
}
// Post file download message
try {
if (typeof window !== 'undefined') {
window.postMessage({
type: 'api_download_data',
status: 'complete',
task_id: task_id,
endpoint: endpoint,
filename: filename,
size_total: 0,
size_loaded: 0,
percent_completed: 0,
},
'*'
);
}
} catch (error) {
console.log('Error posting message to window:', error);
}
return null; // Returning null since there were no results
}
if (log_lvl) {
console.log(`Base URL: ${api_cfg['base_url']} | Endpoint: ${endpoint}`);
console.log('Error Message:', error.message); // Is this needed here or below in the in the else portion???
if (error.response) {
// The request was made and the server responded with a status code that falls out of the range of 2xx
console.log('Error Response Data', error.response.data);
console.log('Error Response Status', error.response.status);
console.log('Error Response Headers', error.response.headers);
} else if (error.request) {
// The request was made but no response was received `error.request` is an instance of XMLHttpRequest in the browser and an instance of http.ClientRequest in node.js
if (log_lvl > 1) {
console.log('Error Request', error.request);
}
} else {
// Something happened in setting up the request that triggered an Error
console.log('Error Message', error.message);
}
}
if (log_lvl > 2) {
console.log('Error:', error);
console.log(error.config);
}
if (error.code === 'ECONNABORTED') {
// Timeout Error (You can implement retry here where suitable)
console.log('Timeout Error: ', error.message);
}
if (log_lvl) {
console.log('The response was an error. Returning false.');
}
return false; // Returning false since something may have gone wrong. This includes timeouts. Also more in line with what the API returns.
// return error;
});
if (log_lvl > 1) {
// console.log(`Response Data: ${response_data_promise}`);
console.log(`Response Data:`, response_data_promise);
// console.log(response_data_promise);
}
if (response_data_promise) {
// The most common and expected response.
// console.log('Returning result. This is generally expected.');
return response_data_promise;
} else if (response_data_promise === null) {
// Less common, but expected response if no results were returned.
if (log_lvl) {
console.log('Returning null. This is expected if no results were found. (404)');
}
return response_data_promise;
} else if (response_data_promise === false) {
// Not common, but expected response if the request to the API had an issue.
console.log('Returning false. There may have been an issue with this request.');
return response_data_promise;
} else {
// This generally should not happen. It likely means the query was bad or an API issue.
console.log('Returning (JSON/text) unknown. This should not happen in most cases.');
Promise.reject(new Error('fail')).then(resolved, rejected);
}
// Handle the case where a Blob is expected to be returned.
} else {
// console.log('Expecting a Blob to be returned...');
let response_data_promise = await axios_api.get(
endpoint,
{
params: params,
responseType: 'blob',
onDownloadProgress: (progressEvent) => {
let percent_completed = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
);
console.log('GET Blob Progress:', progressEvent.progress, '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 {
if (typeof window !== 'undefined') {
window.postMessage({
type: 'api_download_blob',
status: 'downloading',
task_id: task_id,
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);
}
}
}
)
.then(function (response) {
if (log_lvl) {
console.log(`GET (blob) Response: status=${response.status} statusText=${response.statusText} baseURL=${response.config.baseURL} url=${response.config.url} method=${response.config.method} headers=${response.config.headers} params=${response.config.params}`);
}
if (log_lvl > 1) {
console.log('GET (blob) Response:', response);
}
const { data, headers } = response;
// Careful if this download filename needs to be changed to a different file extension. The browser/client may not know how to handle it.
if (filename) {
} else if (headers['content-disposition']) {
filename = headers['content-disposition'].replace(/\w+;filename=(.*)/, '$1');
} else {
filename = 'unknown_file.ext';
}
// WARNING: This needs to be tied to an object type and ID. This is a temporary solution.
try {
if (typeof window !== 'undefined') {
window.postMessage({
type: 'api_download_blob',
status: 'complete',
task_id: task_id,
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}`);
}
const url = window.URL.createObjectURL(new Blob([response.data]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', filename);
document.body.appendChild(link);
link.click();
return true;
} else {
return response;
}
})
.catch(function (error) {
// Handle the common and expected 404 "error" first
if (error.response && error.response.status === 404) {
if (log_lvl) {
console.log('The response was a 404 not found "error". Returning null.');
}
if (log_lvl > 1) {
console.log(error.response);
}
if (log_lvl > 2) {
console.log(error);
}
// Post file download message
try {
if (typeof window !== 'undefined') {
window.postMessage({
type: 'api_download_blob',
status: 'complete',
task_id: task_id,
endpoint: endpoint,
filename: filename,
size_total: 0,
size_loaded: 0,
percent_completed: 0,
},
'*'
);
}
} catch (error) {
console.log('Error posting message to window:', error);
}
return null; // Returning null since there were no results
}
if (log_lvl) {
console.log(`Base URL: ${api_cfg['base_url']} | Endpoint: ${endpoint}`);
console.log('Error Message:', error.message); // Is this needed here or below in the in the else portion???
if (error.response) {
// The request was made and the server responded with a status code that falls out of the range of 2xx
console.log('Error Response Data', error.response.data);
console.log('Error Response Status', error.response.status);
console.log('Error Response Headers', error.response.headers);
} else if (error.request) {
// The request was made but no response was received `error.request` is an instance of XMLHttpRequest in the browser and an instance of http.ClientRequest in node.js
if (log_lvl > 1) {
console.log('Error Request', error.request);
}
} else {
// Something happened in setting up the request that triggered an Error
console.log('Error Message', error.message);
}
}
if (error.code === 'ECONNABORTED') {
// Timeout Error (You can implement retry here where suitable)
console.log('Timeout Error: ', error.message);
}
if (log_lvl) {
console.log('The response was an error. Returning false.');
}
return false; // Returning false since something may have gone wrong. This includes timeouts. Also more in line with what the API returns.
// return error;
});
if (response_data_promise) {
// The most common and expected response.
// console.log('Returning result. This is generally expected.');
// let test_blob = new Blob([response_data_promise.data]);
// console.log(test_blob);
// return test_blob;
// console.log(response_data_promise.blob());
return response_data_promise;
} else if (response_data_promise === null) {
// Less common, but expected response if no results were returned.
if (log_lvl) {
console.log('Returning null. This is expected if no results were found. (404)');
}
return response_data_promise;
} else if (response_data_promise === false) {
// Not common, but expected response if the request to the API had an issue.
console.log('Returning false. There may have been an issue with this request.');
return response_data_promise;
} else {
// This generally should not happen. It likely means the query was bad or an API issue.
console.log('Returning (blob) unknown. This should not happen in most cases.');
Promise.reject(new Error('fail')).then(resolved, rejected);
}
}
}
function resolved(result: any) {
console.log('Resolved');
}
function rejected(result: any) {
console.error(result);
}

View File

@@ -0,0 +1,60 @@
import axios from 'axios';
// Updated 2024-05-23
export let patch_object = async function patch_object(
{
api_cfg=null,
endpoint='',
params={},
data={},
return_meta=false,
log_lvl = 3
}: {
api_cfg: any,
endpoint: string,
params?: any,
data?: any,
return_meta?: boolean,
log_lvl?: number
}
) {
console.log('*** patch_object() XXXX ***');
if (log_lvl) {
// console.log(api_cfg);
console.log(endpoint);
console.log(params);
if (log_lvl > 1) {
console.log(data);
}
// console.log(return_meta);
// console.log(as_list);
}
let axios_api = axios.create({
baseURL: api_cfg['base_url'],
/* other custom settings */
});
axios_api.defaults.headers = api_cfg['headers'];
let response_data = await axios_api.patch(endpoint, data, { params: params })
.then(function (response) {
console.log(response.data);
return response.data['data'];
//return response.data;
})
.catch(function (error) {
if (error.response && error.response.status === 404) {
return null; // Returning null since there were no results
}
console.log(error);
return false; // Returning false since something may have gone wrong. Also more in line with what the API returns.
// return error;
});
if (log_lvl > 1) {
console.log(response_data);
}
return response_data;
}

View File

@@ -0,0 +1,224 @@
import axios from 'axios';
export let temp_post_blob_percent_completed = 0;
export let post_blob_percent_completed = temp_post_blob_percent_completed;
export let temp_post_object_percent_completed = 0;
export let post_object_percent_completed = temp_post_object_percent_completed;
// Updated 2024-05-23
export let post_object = async function post_object(
{
api_cfg=null,
endpoint='',
params={},
data={},
form_data=null,
return_meta=false,
return_blob=false,
filename='',
auto_download=false,
// The task_id value should be a random string that is unique to the task. This is used to identify the task in the message event.
task_id=crypto.randomUUID(),
log_lvl=0
}: {
api_cfg: any,
endpoint: string,
params?: any,
data?: any,
form_data?: any,
return_meta?: boolean,
return_blob?: boolean,
filename?: string,
auto_download?: boolean,
task_id?: string,
log_lvl?: number
}
) {
if (log_lvl) {
console.log(`*** post_object() *** Endpoint: ${endpoint} Task ID: ${task_id}`);
console.log('Params:', params);
if (log_lvl > 1) {
console.log('Data:', data);
console.log(typeof data);
console.log(`Base URL: ${api_cfg['base_url']}`);
console.log('API Config:', api_cfg);
}
if (log_lvl > 2) {
console.log(`Return Meta: ${return_meta}`);
console.log(`Return Blob: ${return_blob}`);
console.log(`Filename: ${filename}`);
console.log(`Auto Download: ${auto_download}`);
}
// console.log(return_meta);
}
let axios_api = axios.create({
baseURL: api_cfg['base_url'],
/* other custom settings */
});
axios_api.defaults.headers = api_cfg['headers'];
console.log('Axios API', axios_api);
// console.log('Axios API POST', axios_api.post);
// if (typeof data == 'FormData') {
if (form_data) {
axios_api.defaults.headers['content-type'] = 'multipart/form-data';
data = form_data;
} else {
axios_api.defaults.headers['content-type'] = 'application/json';
}
if (!return_blob) {
let response_data = await axios_api.post(
endpoint,
data,
{
params: params,
onUploadProgress: (progressEvent) => {
let percent_completed = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
);
console.log('POST Progress:', progressEvent.progress, 'Total:', progressEvent.total, 'Loaded:', progressEvent.loaded, 'Percent Completed', percent_completed);
temp_post_object_percent_completed = percent_completed;
try {
window.postMessage({
type: 'api_post_json_form',
status: 'uploading',
task_id: task_id,
endpoint: endpoint,
size_total: progressEvent.total,
size_loaded: progressEvent.loaded,
percent_completed: percent_completed,
progress: progressEvent.progress,
rate: progressEvent.rate,
},
'*'
);
} catch (error) {
console.log('Error posting message to window:', error);
}
}
}
)
.then(function (response) {
console.log('POST Response Data:', response.data);
try {
window.postMessage({
type: 'api_post_json_form',
status: 'complete',
task_id: task_id,
endpoint: endpoint,
size_total: 0,
size_loaded: 0,
percent_completed: 100,
progress: 100,
rate: 0,
},
'*'
);
} catch (error) {
console.log('Error posting message to window:', error);
}
if (response.data['data'].result === null) {
// This should mean that the request was successful, but a result of None/null was returned from Aether API.
// console.log('Returning null after POST');
return null;
} else {
// This should mean that the request was successful, and a result with data was returned from Aether API.
// console.log('Returning data after POST');
return response.data['data'];
}
//return response.data;
})
.catch(function (error) {
if (error.response && error.response.status === 404) {
return null; // Returning null since there were no results
}
console.log(error);
return false; // Returning false since something may have gone wrong. Also more in line with what the API returns.
// return error;
});
if (log_lvl > 1) {
console.log('Response Data:', response_data);
}
axios_api.defaults.headers['content-type'] = 'application/json';
return response_data;
} else {
// console.log('Expecting a Blob to be returned...');
let response_data_promise = await axios_api.post(
endpoint,
data,
{
params: params,
responseType: 'blob',
onDownloadProgress: (progressEvent) => {
let percent_completed = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
);
console.log('POST Blob Progress:', progressEvent.progress, 'Total:', progressEvent.total, 'Loaded:', progressEvent.loaded, 'Percent Completed', percent_completed);
temp_post_blob_percent_completed = percent_completed;
}
}
)
.then(function (response) {
if (log_lvl) {
console.log(response);
}
const { data, headers } = response
console.log(headers);
if (filename) {
} else if (headers['content-disposition']) {
filename = headers['content-disposition'].replace(/\w+;filename=(.*)/, '$1');
} else {
filename = 'unknown_file.ext';
}
if (auto_download) {
const url = window.URL.createObjectURL(new Blob([response.data]));
const link = document.createElement('a');
link.href = url;
// link.setAttribute('download', 'event_exhibit_tracking_export.xlsx'); //or any other extension
link.setAttribute('download', filename); //or any other extension
document.body.appendChild(link);
link.click();
return true;
} else {
return response;
}
});
if (response_data_promise) {
// The most common and expected response.
// console.log('Returning result. This is generally expected.');
// let test_blob = new Blob([response_data_promise.data]);
// console.log(test_blob);
// return test_blob;
// console.log(response_data_promise.blob());
return response_data_promise;
} else {
// This generally should not happen. It likely means the query was bad or an API issue.
console.log('Returning unknown. This should not happen in most cases.');
Promise.reject(new Error('fail')).then(resolved, rejected);
}
}
}
function resolved(result: any) {
console.log('Resolved');
}
function rejected(result: any) {
console.error(result);
}

View File

@@ -0,0 +1,637 @@
import type { key_val } from '$lib/ae_stores';
import { api } from '$lib/api';
import { db_archives } from "$lib/db_archives";
import { load_ae_obj_li__archive_content } from "$lib/ae_archives__archive_content";
let ae_promises: key_val = {};
// Updated 2024-09-25
export async function load_ae_obj_id__archive(
{
api_cfg,
archive_id,
inc_content_li = false,
try_cache = true,
log_lvl = 0
}: {
api_cfg: any,
archive_id: string,
inc_content_li?: boolean,
try_cache?: boolean,
log_lvl?: number
}
) {
console.log(`*** load_ae_obj_id__archive() *** archive_id=${archive_id}`);
let params = {};
ae_promises.load__archive_obj = await api.get_ae_obj_id_crud({
api_cfg: api_cfg,
obj_type: 'archive',
obj_id: archive_id, // NOTE: This is the FQDN, not normally the ID.
use_alt_table: true, // NOTE: This will use the table_name_alt value instead of the table_name value in the API config.
use_alt_base: false, // NOTE: This will use the base_name_alt value instead of the base_name value in the API config.
params: params,
log_lvl: log_lvl
})
.then(function (archive_obj_get_result) {
if (archive_obj_get_result) {
if (try_cache) {
// This is expecting a list
db_save_ae_obj_li__archive({
obj_type: 'archive',
obj_li: [archive_obj_get_result]
});
}
return archive_obj_get_result;
} else {
console.log('No results returned.');
return null;
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
});
if (log_lvl) {
console.log('ae_promises.load__archive_obj:', ae_promises.load__archive_obj);
}
if (inc_content_li) {
// Load the contents for the archive
if (log_lvl) {
console.log(`Need to load the content list for the archive now`);
}
let load_archive_content_obj_li = load_ae_obj_li__archive_content({
api_cfg: api_cfg,
for_obj_type: 'archive',
for_obj_id: archive_id,
params: {qry__enabled: 'all', qry__limit: 25},
try_cache: try_cache,
log_lvl: log_lvl
})
.then((archive_content_obj_li) => {
if (log_lvl) {
console.log(`archive_content_obj_li = `, archive_content_obj_li);
}
return archive_content_obj_li;
});
if (log_lvl) {
console.log(`archive_content_obj_li = `, load_archive_content_obj_li);
}
ae_promises.load__archive_obj.archive_content_li = load_archive_content_obj_li;
}
return ae_promises.load__archive_obj;
}
// Updated 2024-09-25
export async function load_ae_obj_li__archive(
{
api_cfg,
for_obj_type = 'account',
for_obj_id,
inc_content_li = false,
order_by_li = {'priority': 'DESC', 'sort': 'DESC', 'name': 'ASC', 'updated_on': 'DESC', 'created_on': 'DESC'},
params = {},
try_cache = true,
log_lvl = 0
}: {
api_cfg: any,
for_obj_type: string,
for_obj_id: string,
inc_content_li?: boolean,
order_by_li?: key_val,
params?: key_val,
try_cache?: boolean,
log_lvl?: number
}
) {
console.log(`*** load_ae_obj_li__archive() *** for_obj_type=${for_obj_type} for_obj_id=${for_obj_id}`);
let enabled: string = (params.qry__enabled ?? 'enabled'); // all, disabled, enabled
let hidden: string = (params.qry__hidden ?? 'not_hidden'); // all, hidden, not_hidden
let limit: number = (params.qry__limit ?? 99); // 99
let offset: number = (params.qry__offset ?? 0); // 0
let params_json: key_val = {};
// console.log('params_json:', params_json);
ae_promises.load__archive_obj_li = await api.get_ae_obj_li_for_obj_id_crud({
api_cfg: api_cfg,
obj_type: 'archive',
for_obj_type: for_obj_type,
for_obj_id: for_obj_id,
use_alt_table: true, // NOTE: This will use the table_name_alt value instead of the table_name value in the API config.
use_alt_base: false, // NOTE: This will use the base_name_alt value instead of the base_name value
enabled: enabled,
hidden: hidden,
order_by_li: order_by_li,
limit: limit,
offset: offset,
params_json: params_json,
params: params,
log_lvl: log_lvl
})
.then(function (archive_obj_li_get_result) {
if (archive_obj_li_get_result) {
if (try_cache) {
db_save_ae_obj_li__archive({
obj_type: 'archive',
obj_li: archive_obj_li_get_result
});
}
return archive_obj_li_get_result;
} else {
return [];
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
});
if (log_lvl) {
console.log('ae_promises.load__archive_obj_li:', ae_promises.load__archive_obj_li);
}
if (inc_content_li) {
// Load the contents for the archives
if (log_lvl) {
console.log(`Need to load the content list for each archive now`);
}
for (let i = 0; i < ae_promises.load__archive_obj_li.length; i++) {
let archive_obj = ae_promises.load__archive_obj_li[i];
let archive_id = archive_obj.archive_id_random;
let load_archive_content_obj_li = load_ae_obj_li__archive_content({
api_cfg: api_cfg,
for_obj_type: 'archive',
for_obj_id: archive_id,
params: {qry__enabled: enabled, qry__limit: limit},
try_cache: try_cache,
log_lvl: log_lvl
})
.then((archive_content_obj_li) => {
if (log_lvl) {
console.log(`archive_content_obj_li = `, archive_content_obj_li);
}
return archive_content_obj_li;
});
if (log_lvl) {
console.log(`load_archive_content_obj_li = `, load_archive_content_obj_li);
}
}
}
return ae_promises.load__archive_obj_li;
}
// Updated 2024-09-25
export async function create_ae_obj__archive(
{
api_cfg,
account_id,
data_kv,
params={},
log_lvl=0
}: {
api_cfg: any,
account_id: string,
data_kv: key_val,
params?: key_val,
log_lvl?: number
}
) {
console.log(`*** create_ae_obj__archive() *** account_id=${account_id}`);
ae_promises.create__archive = await api.create_ae_obj_crud({
api_cfg: api_cfg,
obj_type: 'archive',
fields: {
account_id_random: account_id,
...data_kv
},
key: api_cfg.api_crud_super_key,
params: params,
return_obj: true,
log_lvl: log_lvl
})
.then(function (archive_obj_create_result) {
if (archive_obj_create_result) {
db_save_ae_obj_li__archive(
{
obj_type: 'archive',
obj_li: [archive_obj_create_result]
});
return archive_obj_create_result;
} else {
return null;
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
})
.finally(function () {
});
if (log_lvl) {
console.log('ae_promises.create__archive:', ae_promises.create__archive);
}
return ae_promises.create__archive;
}
// Updated 2024-09-25
export async function update_ae_obj__archive(
{
api_cfg,
archive_id,
data_kv,
params = {},
try_cache = true,
log_lvl = 0
}: {
api_cfg: any,
archive_id: string,
data_kv: key_val,
params?: key_val,
try_cache?: boolean,
log_lvl?: number
}
) {
if (log_lvl) {
console.log(`*** update_ae_obj__archive() *** archive_id=${archive_id}`, data_kv);
}
ae_promises.update__archive_obj = await api.update_ae_obj_id_crud({
api_cfg: api_cfg,
obj_type: 'archive',
obj_id: archive_id,
fields: data_kv,
key: api_cfg.api_crud_super_key,
params: params,
return_obj: true,
log_lvl: log_lvl
})
.then(function (archive_obj_update_result) {
if (archive_obj_update_result) {
if (try_cache) {
db_save_ae_obj_li__archive({
obj_type: 'archive', obj_li: [archive_obj_update_result]
});
}
return archive_obj_update_result;
} else {
return null;
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
})
.finally(function () {
});
if (log_lvl) {
console.log('ae_promises.update__archive_obj:', ae_promises.update__archive_obj);
}
return ae_promises.update__archive_obj;
}
// This new function is using CRUD v2. This should allow for more flexibility in the queries.
// Updated 2024-09-25
export async function qry__archive(
{
api_cfg,
archive_id,
qry_str,
qry_files,
qry_start_datetime, // Example greater than: '2024-10-24'
enabled = 'enabled',
hidden = 'not_hidden',
limit = 50,
offset = 0,
params = {},
try_cache = true,
log_lvl = 0
}: {
api_cfg: any,
archive_id: any,
qry_str?: string,
qry_files?: null|boolean,
qry_start_datetime?: null|string, // Greater than this datetime
enabled?: string, // all, disabled, enabled
hidden?: string, // all, hidden, not_hidden
limit?: number,
offset?: number,
params?: any,
try_cache?: boolean,
log_lvl?: number
}
) {
console.log(`*** qry__archive() *** archive_id=${archive_id} qry_str=${qry_str}`);
// let enabled: string = (params.qry__enabled ?? 'enabled'); // all, disabled, enabled
// let hidden: string = (params.qry__hidden ?? 'not_hidden'); // all, hidden, not_hidden
// let limit: number = (params.qry__limit ?? 25); // 99
// let offset: number = (params.qry__offset ?? 0); // 0
let params_json: key_val = {};
// if (qry_str && qry_str.length > 2) {
// params_json['ft_qry'] = {};
// params_json['ft_qry']['default_qry_str'] = qry_str;
// }
params_json['qry'] = [];
if (qry_files === true) {
let qry_param =
{
type: "AND",
field: "file_count_all",
operator: ">",
value: 0
};
params_json['qry'].push(qry_param);
} else if (qry_files === false) {
let qry_param =
{
type: "AND",
field: "file_count_all",
operator: "IS",
value: null
};
params_json['qry'].push(qry_param);
}
if (qry_start_datetime) {
let qry_param =
{
type: "AND",
field: "start_datetime",
operator: ">",
value: qry_start_datetime
};
params_json['qry'].push(qry_param);
}
let order_by_li = {'priority': 'DESC', 'sort': 'DESC', 'start_datetime': 'ASC', 'name': 'ASC', 'updated_on': 'DESC', 'created_on': 'DESC'};
ae_promises.load__archive_obj_li = await api.get_ae_obj_li_for_obj_id_crud_v2({
api_cfg: api_cfg,
obj_type: 'archive',
for_obj_type: 'event',
for_obj_id: archive_id,
use_alt_tbl: true, // NOTE: We want to use the alt table for archive searching
use_alt_mdl: false,
use_alt_exp: false,
enabled: enabled,
hidden: hidden,
order_by_li: order_by_li,
limit: limit,
offset: offset,
params_json: params_json,
params: params,
log_lvl: log_lvl
})
.then(function (archive_obj_li_get_result) {
if (archive_obj_li_get_result) {
db_save_ae_obj_li__archive({
obj_type: 'archive',
obj_li: archive_obj_li_get_result
});
return archive_obj_li_get_result;
} else {
return [];
}
});
if (log_lvl) {
console.log('ae_promises.load__archive_obj_li:', ae_promises.load__archive_obj_li);
}
return ae_promises.load__archive_obj_li;
}
// // Updated 2024-09-25
// export async function search__archive(
// {
// api_cfg,
// account_id,
// poc_agree = null,
// fulltext_search_qry_str,
// ft_content_search_qry_str,
// like_search_qry_str = null,
// file_count = false, // If true then only show those that have a file count
// person_name = null,
// params = {},
// try_cache = true,
// log_lvl = 0
// }: {
// api_cfg: any,
// account_id: any,
// poc_agree?: null|boolean,
// fulltext_search_qry_str?: null|string,
// ft_content_search_qry_str?: null|string,
// like_search_qry_str?: null|string,
// file_count?: boolean,
// person_name?: null|string,
// params?: any,
// try_cache?: boolean,
// log_lvl?: number
// }
// ) {
// console.log(`*** search__archive() *** account_id=${account_id}`);
// let enabled: string = (params.qry__enabled ?? 'enabled'); // all, disabled, enabled
// let hidden: string = (params.qry__hidden ?? 'not_hidden'); // all, hidden, not_hidden
// let limit: number = (params.qry__limit ?? 25); // 99
// let offset: number = (params.qry__offset ?? 0); // 0
// let params_json: key_val = {};
// // if (!fulltext_search_qry_str && !like_search_qry_str) {
// // console.log('No search string provided!!!');
// // return false; // Returning false instead of [] because no search was performed.
// // }
// if (fulltext_search_qry_str || ft_content_search_qry_str) {
// params_json['ft_qry'] = {};
// if (fulltext_search_qry_str && fulltext_search_qry_str.length > 2) {
// params_json['ft_qry']['default_qry_str'] = fulltext_search_qry_str;
// }
// if (ft_content_search_qry_str && ft_content_search_qry_str.length > 2) {
// params_json['ft_qry']['archive_content_li_qry_str'] = ft_content_search_qry_str;
// }
// }
// // Use the AND (AND LIKE) query
// // if (like_search_qry_str || like_content_search_qry_str) {
// // params_json['and_like'] = {};
// // if (like_search_qry_str && like_search_qry_str.length > 2) {
// // params_json['and_like']['default_qry_str'] = like_search_qry_str;
// // }
// // if (like_content_search_qry_str && like_content_search_qry_str.length > 2) {
// // params_json['and_like']['archive_content_li_qry_str'] = like_content_search_qry_str;
// // }
// // }
// // Use the AND (OR LIKE) query
// if (like_search_qry_str || like_content_search_qry_str || like_content_search_qry_str) {
// params_json['or_like'] = {};
// if (like_search_qry_str && like_search_qry_str.length > 2) {
// params_json['or_like']['default_qry_str'] = like_search_qry_str;
// }
// if (like_content_search_qry_str && like_content_search_qry_str.length > 2) {
// params_json['or_like']['archive_content_li_qry_str'] = like_content_search_qry_str;
// }
// if (like_content_search_qry_str && like_content_search_qry_str.length > 2) {
// params_json['or_like']['archive_content_li_qry_str'] = like_content_search_qry_str;
// }
// }
// params_json['and_qry'] = {};
// if (poc_agree) {
// params_json['and_qry']['poc_agree'] = poc_agree;
// }
// if (file_count) {
// params_json['and_qry']['file_count'] = file_count;
// }
// // This should be using a like with surrounded by %'s
// if (person_name) {
// params_json['and_qry']['archive_full_name'] = person_name;
// }
// let order_by_li = {'priority': 'DESC', 'sort': 'DESC', 'name': 'ASC', 'updated_on': 'DESC', 'created_on': 'DESC'};
// ae_promises.load__archive_obj_li = await api.get_ae_obj_li_for_obj_id_crud({
// api_cfg: api_cfg,
// obj_type: 'archive',
// for_obj_type: 'account',
// for_obj_id: account_id,
// use_alt_table: true, // NOTE: We want to use the alt table for archive searching
// use_alt_base: false,
// enabled: enabled,
// hidden: hidden,
// order_by_li: order_by_li,
// limit: limit,
// offset: offset,
// params_json: params_json,
// params: params,
// log_lvl: log_lvl
// })
// .then(function (archive_obj_li_get_result) {
// if (archive_obj_li_get_result) {
// if (try_cache) {
// db_save_ae_obj_li__archive({
// obj_type: 'archive',
// obj_li: archive_obj_li_get_result
// });
// }
// return archive_obj_li_get_result;
// } else {
// return [];
// }
// })
// .catch(function (error) {
// console.log('No results returned or failed.', error);
// })
// .finally(function () {
// });
// if (log_lvl) {
// console.log('ae_promises.load__archive_obj_li:', ae_promises.load__archive_obj_li);
// }
// return ae_promises.load__archive_obj_li;
// }
// This function will loop through the archive_obj_li and save each one to the DB.
// Updated 2024-09-25
export function db_save_ae_obj_li__archive(
{
obj_type,
obj_li,
log_lvl = 0
}: {
obj_type: string,
obj_li: any,
log_lvl?: number
}
) {
if (log_lvl) {
console.log(`*** db_save_ae_obj_li__archive() ***`);
}
if (obj_li && obj_li.length) {
obj_li.forEach(async function (obj: any) {
if (log_lvl) {
console.log(`ae_obj ${obj_type}:`, obj);
}
try {
const id_random = await db_archives.archive.put({
id: obj.archive_id_random,
archive_id: obj.archive_id_random,
code: obj.code,
account_id: obj.account_id_random,
name: obj.name,
description: obj.description,
original_datetime: obj.original_datetime,
original_timezone: obj.original_timezone,
original_location: obj.original_location,
original_url: obj.original_url,
original_url_text: obj.original_url_text,
sort_by: obj.sort_by,
sort_by_desc: obj.sort_by_desc,
cfg_json: obj.cfg_json,
enable: obj.enable,
hide: obj.hide,
priority: obj.priority,
sort: obj.sort,
group: obj.group,
notes: obj.notes,
created_on: obj.created_on,
updated_on: obj.updated_on,
// From SQL view
// archive_content_count: obj.archive_content_count,
// A key value list of the contents
// archive_content_kv: obj.archive_content_kv,
// archive_content_li: obj.archive_content_li,
});
// console.log(`Put obj with ID: ${obj.archive_id_random} or ${id_random}`);
} catch (error) {
let status = `Failed to put ${obj.archive_id_random}: ${error}`;
console.log(status);
}
// const id_random = await db_archives.archive.put(obj);
// console.log(`Put obj with ID: ${obj.archive_id_random}`);
});
return true;
}
}

View File

@@ -0,0 +1,325 @@
import type { key_val } from '$lib/ae_stores';
import { api } from '$lib/api';
import { db_archives } from "$lib/db_archives";
let ae_promises: key_val = {};
// Updated 2024-09-25
export async function load_ae_obj_id__archive_content(
{
api_cfg,
archive_content_id,
try_cache = true,
log_lvl = 0
}: {
api_cfg: any,
archive_content_id: string,
try_cache?: boolean,
log_lvl?: number
}
) {
console.log(`*** load_ae_obj_id__archive_content() *** archive_content_id=${archive_content_id}`);
let params = {};
ae_promises.load__archive_content_obj = await api.get_ae_obj_id_crud({
api_cfg: api_cfg,
obj_type: 'archive_content',
obj_id: archive_content_id, // NOTE: This is the FQDN, not normally the ID.
use_alt_table: false, // NOTE: This will use the table_name_alt value instead of the table_name value in the API config.
use_alt_base: false, // NOTE: This will use the base_name_alt value instead of the base_name value
params: params,
log_lvl: log_lvl
})
.then(function (archive_content_obj_get_result) {
if (archive_content_obj_get_result) {
if (try_cache) {
// This is expecting a list
db_save_ae_obj_li__archive_content({
obj_type: 'archive_content',
obj_li: [archive_content_obj_get_result]
});
}
return archive_content_obj_get_result;
} else {
console.log('No results returned.');
return null;
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
});
return ae_promises.load__archive_content_obj;
}
// Updated 2024-09-25
export async function load_ae_obj_li__archive_content(
{
api_cfg,
for_obj_type = 'archive',
for_obj_id,
order_by_li = {'priority': 'DESC', 'sort': 'DESC', 'start_datetime': 'ASC', 'name': 'ASC', 'updated_on': 'DESC', 'created_on': 'DESC'},
params = {},
try_cache = true,
log_lvl = 0
}: {
api_cfg: any,
for_obj_type: string,
for_obj_id: string,
order_by_li?: key_val,
params?: key_val,
try_cache?: boolean,
log_lvl?: number
}
) {
console.log(`*** load_ae_obj_li__archive_content() *** for_obj_type=${for_obj_type} for_obj_id=${for_obj_id}`);
let enabled: string = (params.qry__enabled ?? 'enabled'); // all, disabled, enabled
let hidden: string = (params.qry__hidden ?? 'not_hidden'); // all, hidden, not_hidden
let limit: number = (params.qry__limit ?? 99); // 99
let offset: number = (params.qry__offset ?? 0); // 0
let params_json: key_val = {};
// console('params_json:', params_json);
ae_promises.load__archive_content_obj_li = await api.get_ae_obj_li_for_obj_id_crud({
api_cfg: api_cfg,
obj_type: 'archive_content',
for_obj_type: for_obj_type,
for_obj_id: for_obj_id,
use_alt_table: true, // NOTE: This will use the table_name_alt value instead of the table_name value in the API config.
use_alt_base: false, // NOTE: This will use the base_name_alt value instead of the base_name value
enabled: enabled,
hidden: hidden,
order_by_li: order_by_li,
limit: limit,
offset: offset,
params_json: params_json,
params: params,
log_lvl: log_lvl
})
.then(function (archive_content_obj_li_get_result) {
if (archive_content_obj_li_get_result) {
if (try_cache) {
db_save_ae_obj_li__archive_content({
obj_type: 'archive_content', obj_li: archive_content_obj_li_get_result
});
}
return archive_content_obj_li_get_result;
} else {
return [];
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
});
if (log_lvl) {
console.log('ae_promises.load__archive_content_obj_li:', ae_promises.load__archive_content_obj_li);
}
return ae_promises.load__archive_content_obj_li;
}
// Updated 2024-09-25
export async function create_ae_obj__archive_content(
{
api_cfg,
archive_id,
data_kv,
params={},
log_lvl=0
}: {
api_cfg: any,
archive_id: string,
data_kv: key_val,
params?: key_val,
log_lvl?: number
}
) {
console.log(`*** create_ae_obj__archive_content() *** archive_id=${archive_id}`);
ae_promises.create__archive_content = await api.create_ae_obj_crud({
api_cfg: api_cfg,
obj_type: 'archive_content',
fields: {
archive_id_random: archive_id,
...data_kv
},
key: api_cfg.api_crud_super_key,
params: params,
return_obj: true,
log_lvl: log_lvl
})
.then(function (archive_content_obj_create_result) {
if (archive_content_obj_create_result) {
db_save_ae_obj_li__archive_content(
{
obj_type: 'archive_content',
obj_li: [archive_content_obj_create_result]
});
return archive_content_obj_create_result;
} else {
return null;
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
})
.finally(function () {
});
if (log_lvl) {
console.log('ae_promises.create__archive_content:', ae_promises.create__archive_content);
}
return ae_promises.create__archive_content;
}
// Updated 2024-09-25
export async function update_ae_obj__archive_content(
{
api_cfg,
archive_content_id,
data_kv,
params = {},
try_cache = true,
log_lvl = 0
}: {
api_cfg: any,
archive_content_id: string,
data_kv: key_val,
params?: key_val,
try_cache?: boolean,
log_lvl?: number
}
) {
if (log_lvl) {
console.log(`*** update_ae_obj__archive_content() *** archive_content_id=${archive_content_id}`, data_kv);
}
ae_promises.update__archive_content_obj = await api.update_ae_obj_id_crud({
api_cfg: api_cfg,
obj_type: 'archive_content',
obj_id: archive_content_id,
fields: data_kv,
key: api_cfg.api_crud_super_key,
params: params,
return_obj: true,
log_lvl: log_lvl
})
.then(function (archive_content_obj_update_result) {
if (archive_content_obj_update_result) {
if (try_cache) {
db_save_ae_obj_li__archive_content({
obj_type: 'archive_content', obj_li: [archive_content_obj_update_result]
});
}
return archive_content_obj_update_result;
} else {
return null;
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
})
.finally(function () {
});
if (log_lvl) {
console.log('ae_promises.update__archive_content_obj:', ae_promises.update__archive_content_obj);
}
return ae_promises.update__archive_content_obj;
}
// This function will loop through the archive_content_obj_li and save each one to the DB.
// Updated 2024-09-25
export function db_save_ae_obj_li__archive_content(
{
obj_type,
obj_li,
log_lvl = 0
}: {
obj_type: string,
obj_li: any,
log_lvl?: number
}
) {
if (log_lvl) {
console.log(`*** db_save_ae_obj_li__archive_content() ***`);
}
if (obj_li && obj_li.length) {
obj_li.forEach(async function (obj: any) {
if (log_lvl) {
console.log(`ae_obj ${obj_type}:`, obj);
}
try {
const id_random = await db_archives.content.put({
id: obj.archive_content_id_random,
archive_content_id: obj.archive_content_id_random,
archive_id: obj.archive_id_random,
archive_content_type: obj.archive_content_type,
name: obj.name,
description: obj.description,
content_html: obj.content_html,
content_json: obj.content_json,
url: obj.url,
url_text: obj.url_text,
hosted_file_id: obj.hosted_file_id,
file_path: obj.file_path,
filename: obj.filename,
file_extension: obj.file_extension,
original_datetime: obj.original_datetime,
original_timezone: obj.original_timezone,
original_location: obj.original_location,
original_url: obj.original_url,
original_url_text: obj.original_url_text,
enable_for_public: obj.enable_for_public,
cfg_json: obj.cfg_json,
enable: obj.enable,
hide: obj.hide,
priority: obj.priority,
sort: obj.sort,
group: obj.group,
notes: obj.notes,
created_on: obj.created_on,
updated_on: obj.updated_on,
// From SQL view
archive_code: obj.archive_code,
archive_name: obj.archive_name,
});
// console.log(`Put obj with ID: ${obj.archive_content_id_random} or ${id_random}`);
} catch (error) {
let status = `Failed to put ${obj.archive_content_id_random}: ${error}`;
console.log(status);
}
// const id_random = await db_archives.content.put(obj);
// console.log(`Put obj with ID: ${obj.archive_content_id_random}`);
});
return true;
}
}

View File

@@ -0,0 +1,36 @@
// This file is used to export all the functions that are used for Aether Posts related functions.
import {
load_ae_obj_id__archive,
load_ae_obj_li__archive,
create_ae_obj__archive,
update_ae_obj__archive,
// qry__archive,
db_save_ae_obj_li__archive,
} from "$lib/ae_archives__archive";
import {
load_ae_obj_id__archive_content,
load_ae_obj_li__archive_content,
create_ae_obj__archive_content,
update_ae_obj__archive_content,
// qry__archive_content,
db_save_ae_obj_li__archive_content,
} from "$lib/ae_archives__archive_content";
let export_obj = {
load_ae_obj_id__archive: load_ae_obj_id__archive,
load_ae_obj_li__archive: load_ae_obj_li__archive,
create_ae_obj__archive: create_ae_obj__archive,
update_ae_obj__archive: update_ae_obj__archive,
db_save_ae_obj_li__archive: db_save_ae_obj_li__archive,
load_ae_obj_id__archive_content: load_ae_obj_id__archive_content,
load_ae_obj_li__archive_content: load_ae_obj_li__archive_content,
create_ae_obj__archive_content: create_ae_obj__archive_content,
update_ae_obj__archive_content: update_ae_obj__archive_content,
db_save_ae_obj_li__archive_content: db_save_ae_obj_li__archive_content,
};
export let archives_func = export_obj;

319
src/lib/ae_core__person.ts Normal file
View File

@@ -0,0 +1,319 @@
import type { key_val } from '$lib/ae_stores';
import { api } from '$lib/api';
import { db_core } from "$lib/db_core";
let ae_promises: key_val = {};
// Updated 2024-07-17
export async function handle_load_ae_obj_id__person(
{
api_cfg,
person_id,
try_cache=false,
log_lvl=0
}: {
api_cfg: any,
person_id: string,
try_cache?: boolean,
log_lvl?: number
}
) {
console.log(`*** handle_load_ae_obj_id__person() *** person_id=${person_id}`);
let params = {};
ae_promises.load__person_obj = await api.get_ae_obj_id_crud({
api_cfg: api_cfg,
obj_type: 'person',
obj_id: person_id, // NOTE: This is the FQDN, not normally the ID.
use_alt_table: false, // NOTE: This will use the table_name_alt value instead of the table_name value in the API config.
use_alt_base: false, // NOTE: This will use the base_name_alt value instead of the base_name value
params: params,
log_lvl: log_lvl
})
.then(function (person_obj_get_result) {
if (person_obj_get_result) {
// This is expecting a list
handle_db_save_ae_obj_li__person({obj_type: 'person', obj_li: [person_obj_get_result]});
return person_obj_get_result;
} else {
console.log('No results returned.');
return null;
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
});
return ae_promises.load__person_obj;
}
// Updated 2024-07-17
export async function handle_load_ae_obj_li__person(
{
api_cfg,
account_id,
params={},
try_cache=true,
log_lvl=0
}: {
api_cfg: any,
account_id: string,
params?: key_val,
try_cache?: boolean,
log_lvl?: number
}
) {
console.log(`*** handle_load_ae_obj_li__person() *** account_id=${account_id}`);
let enabled: string = (params.qry__enabled ?? 'enabled'); // all, disabled, enabled
let hidden: string = (params.qry__hidden ?? 'not_hidden'); // all, hidden, not_hidden
let limit: number = (params.qry__limit ?? 99); // 99
let offset: number = (params.qry__offset ?? 0); // 0
let params_json: key_val = {};
// console.log('params_json:', params_json);
ae_promises.load__person_obj_li = await api.get_ae_obj_li_for_obj_id_crud({
api_cfg: api_cfg,
obj_type: 'person',
for_obj_type: 'account',
for_obj_id: account_id,
use_alt_table: false, // NOTE: This will use the table_name_alt value instead of the table_name value in the API config.
use_alt_base: false, // NOTE: This will use the base_name_alt value instead of the base_name value
enabled: enabled,
hidden: hidden,
order_by_li: {'given_name': 'ASC', 'family_name': 'ASC', 'updated_on': 'DESC', 'created_on': 'DESC'},
limit: limit,
offset: offset,
params_json: params_json,
params: params,
log_lvl: log_lvl
})
.then(function (person_obj_li_get_result) {
if (person_obj_li_get_result) {
handle_db_save_ae_obj_li__person({obj_type: 'person', obj_li: person_obj_li_get_result});
return person_obj_li_get_result;
} else {
return [];
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
});
console.log('ae_promises.load__person_obj_li:', ae_promises.load__person_obj_li);
return ae_promises.load__person_obj_li;
}
// Updated 2024-06-24
export async function handle_create_ae_obj__person(
{
api_cfg,
user_id,
data_kv,
params={},
log_lvl=0
}: {
api_cfg: any,
user_id?: string,
data_kv: key_val,
params?: key_val,
log_lvl?: number
}
) {
console.log(`*** handle_create_ae_obj__person() *** user_id=${user_id}`);
ae_promises.create__person = await api.create_ae_obj_crud({
api_cfg: api_cfg,
obj_type: 'person',
fields: {
user_id_random: user_id,
...data_kv
},
key: api_cfg.api_crud_super_key,
params: params,
return_obj: true,
log_lvl: log_lvl
})
.then(function (person_obj_create_result) {
if (person_obj_create_result) {
handle_db_save_ae_obj_li__person(
{
obj_type: 'person', obj_li: [person_obj_create_result]
});
return person_obj_create_result;
} else {
return null;
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
})
.finally(function () {
});
if (log_lvl) {
console.log('ae_promises.create__person:', ae_promises.create__person);
}
return ae_promises.create__person;
}
// Updated 2024-07-17
export async function handle_update_ae_obj__person(
{
api_cfg,
person_id,
data_kv,
params={},
log_lvl=0
}: {
api_cfg: any,
person_id: string,
data_kv: key_val,
params?: key_val,
log_lvl?: number
}
) {
console.log(`*** handle_update_ae_obj__person() *** person_id=${person_id}`);
ae_promises.update__person_obj = await api.update_ae_obj_id_crud({
api_cfg: api_cfg,
obj_type: 'person',
obj_id: person_id, // NOTE: This is the FQDN, not normally the ID.
fields: data_kv,
key: api_cfg.api_crud_super_key,
params: params,
return_obj: true,
log_lvl: log_lvl
})
.then(function (person_obj_update_result) {
if (person_obj_update_result) {
handle_db_save_ae_obj_li__person({obj_type: 'person', obj_li: [person_obj_update_result]});
return person_obj_update_result;
} else {
return null;
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
})
.finally(function () {
});
if (log_lvl) {
console.log('ae_promises.update__person_obj:', ae_promises.update__person_obj);
}
return ae_promises.update__person_obj;
}
// Updated 2024-06-10
export function handle_db_save_ae_obj_li__person(
{
obj_type,
obj_li,
log_lvl=0
}: {
obj_type: string,
obj_li: any,
log_lvl?: number
}
) {
if (log_lvl) {
console.log(`*** handle_db_save_ae_obj_li__person() ***`);
}
if (obj_li && obj_li.length) {
obj_li.forEach(async function (obj: any) {
if (log_lvl) {
console.log(`ae_obj ${obj_type}:`, obj);
}
try {
const id_random = await db_core.person.put({
id: obj.person_id_random,
// id_random: obj.person_id_random,
person_id: obj.person_id_random,
person_id_random: obj.person_id_random,
external_id: obj.external_id,
external_sys_id: obj.external_sys_id,
code: obj.code,
account_id: obj.account_id_random,
account_id_random: obj.account_id_random,
person_profile_id: obj.person_profile_id_random,
person_profile_id_random: obj.person_profile_id_random, // The new table person_profile will be used soon...
user_id: obj.user_id_random,
user_id_random: obj.user_id_random,
pronouns: obj.pronouns,
informal_name: obj.informal_name,
title_names: obj.title_names,
given_name: obj.given_name,
middle_name: obj.middle_name,
family_name: obj.family_name,
designations: obj.designations,
professional_title: obj.professional_title,
full_name: obj.full_name,
affiliations: obj.affiliations,
primary_email: obj.primary_email,
biography: obj.biography,
agree: obj.agree,
comments: obj.comments,
allow_auth_key: obj.allow_auth_key, // For sign in without password
// auth_key: obj.auth_key,
passcode: obj.passcode,
data_json: obj.data_json,
enable: obj.enable,
hide: obj.hide,
priority: obj.priority,
sort: obj.sort,
group: obj.group,
notes: obj.notes,
created_on: obj.created_on,
updated_on: obj.updated_on,
// From SQL view
username: obj.username,
user_name: obj.user_name,
user_email: obj.user_email,
user_allow_auth_key: obj.user_allow_auth_key, // For sign in without password
user_super: obj.user_super,
user_manager: obj.user_manager,
user_administrator: obj.user_administrator,
user_public: obj.user_public,
});
// console.log(`Put obj with ID: ${obj.person_id_random} or ${id_random}`);
} catch (error) {
let status = `Failed to put ${obj.person_id_random}: ${error}`;
console.log(status);
}
// const id_random = await db_core.person.put(obj);
// console.log(`Put obj with ID: ${obj.person_id_random}`);
});
return true;
}
}

115
src/lib/ae_core__qr_code.ts Normal file
View File

@@ -0,0 +1,115 @@
import type { key_val } from '$lib/ae_stores';
import { api } from '$lib/api';
import { db_core } from "$lib/db_core";
let ae_promises: key_val = {};
// Updated 2024-07-18
export async function generate_qr_code(
{
api_cfg,
account_id,
qr_type, // mecard, obj, str, vcard
qr_id, // This is essentially the filename it can be found at /qr/{account_id}/{qr_id}
qr_data, // vcard fields:
obj_type,
obj_id,
str, // For encoding a string (like a URL) into a QR code.
return_blob=true, // blob or url?
try_cache=false,
log_lvl=0
}: {
api_cfg: any,
account_id: string,
qr_type: string,
qr_id: string,
qr_data?: any,
obj_type?: string,
obj_id?: string,
str?: string,
return_blob?: boolean,
try_cache?: boolean,
log_lvl?: number
}
) {
if (log_lvl) {
console.log(`*** generate_qr_code() *** qr_id=${qr_id}`);
}
let endpoint = `/qr/${account_id}/${qr_id}`;
if (log_lvl) {
console.log('Endpoint', endpoint);
}
let params: key_val = {
'regen': true, // Regenerate the file even if nothing has changed.
'return_file': return_blob,
'qr_type': qr_type, // mecard, obj, vcard
'qr_send': return_blob
};
if (qr_type == 'vcard') {
if (qr_data.informal_name) {
params['n'] = `${qr_data.family_name};${qr_data.given_name};${qr_data.informal_name}`;
} else {
params['n'] = `${qr_data.family_name};${qr_data.given_name}`;
}
params['fn'] = qr_data.full_name_override;
if (qr_data.affiliations) { params['org'] = qr_data.affiliations; }
// url
params['email'] = qr_data.email;
if (qr_data.phone) { params['tel'] = qr_data.phone; }
params['adr'] = qr_data.location_override;
if (qr_data.address_line_1) { params['adr_str'] = qr_data.address_line_1; }
params['adr_loc'] = qr_data.city;
params['adr_reg'] = qr_data.state_province;
params['adr_postal'] = qr_data.postal_code;
params['adr_country'] = qr_data.country;
} else if (qr_type == 'obj') {
params['obj_type'] = obj_type;
params['obj_id'] = obj_id;
} else if (qr_type == 'str') {
params['str'] = str;
}
if (log_lvl) {
console.log('Params', params);
}
// let filename = `qr_${$ae_loc.account_id}_${qr_id}_${qr_type}.png`;
let filename = null;
ae_promises.generate_qr_code = await api.get_object({
api_cfg: api_cfg,
endpoint: endpoint,
params: params,
return_blob: return_blob,
filename: filename,
auto_download: false,
log_lvl: log_lvl
});
console.log('QR code generated done!?');
if (return_blob) {
let img_blob = new Blob([ae_promises.generate_qr_code.data]);
let img_obj_url = URL.createObjectURL(img_blob);
// console.log(img_obj_url);
// return img_blob;
return img_obj_url;
}
// let img_blob = new Blob([ae_promises.generate_qr_code.data]);
// console.log(img_blob);
// let img_obj_url = URL.createObjectURL(img_blob);
// console.log(img_obj_url);
// let qr_img_src = img_obj_url;
return ae_promises.generate_qr_code;
}

View File

@@ -0,0 +1,420 @@
import { browser } from '$app/environment';
import type { key_val } from '$lib/ae_stores';
import { api } from '$lib/api';
import {
handle_load_ae_obj_id__person,
handle_load_ae_obj_li__person,
handle_create_ae_obj__person,
handle_update_ae_obj__person,
// handle_db_save_ae_obj_li__person
} from "$lib/ae_core__person";
import {
generate_qr_code,
} from "$lib/ae_core__qr_code";
let ae_promises: key_val = {}; // Promise<any>;
// Updated 2024-10-02
async function check_hosted_file_obj_w_hash(
{
api_cfg,
hosted_file_hash,
check_for_local = true, // Forces a check on the host server for the file.
params = {},
return_meta = false,
log_lvl = 0
} : {
api_cfg: any,
hosted_file_hash: string,
check_for_local?: boolean,
params?: key_val,
return_meta?: boolean,
log_lvl?: number
}
) {
console.log('*** stores_event_api.js: check_hosted_file_obj_w_hash() ***');
const endpoint = `/hosted_file/hash/${hosted_file_hash}`;
if (check_for_local) {
params['check_for_local'] = true;
}
let check_hosted_file_obj_w_hash_get_promise = await api.get_object({
api_cfg: api_cfg,
endpoint: endpoint,
params: params,
return_meta: return_meta,
log_lvl: log_lvl
});
return check_hosted_file_obj_w_hash_get_promise;
}
// Updated 2024-03-29
async function handle_load_ae_obj_id__site_domain(
{
api_cfg,
fqdn,
try_cache = false,
timeout = 7000,
log_lvl = 0
}: {
api_cfg: any,
fqdn: string,
try_cache?: boolean,
timeout?: number,
log_lvl?: number
}
) {
console.log(`*** handle_load_ae_obj_id__site_domain() *** fqdn=${fqdn}`);
let no_account_id = false;
if (!api_cfg.account_id) {
no_account_id = true;
// api_cfg.headers['x_account_id'] = 'nothing here';
}
no_account_id = true;
let params = {};
// ae_loc.hub.site_domain_id_qry_status = 'loading';
ae_promises.load__site_domain_obj = api.get_ae_obj_id_crud({
api_cfg: api_cfg,
no_account_id: no_account_id,
obj_type: 'site_domain',
obj_id: fqdn, // NOTE: This is the FQDN, not normally the ID.
use_alt_table: true, // NOTE: This will use the table_name_alt value (v_site_domain_fqdn_id) instead of the table_name value in the API config.
use_alt_base: true, // NOTE: This will use the base_name_alt value (Site_Domain_FQDN_ID_Base) instead of the base_name value in the API config.
params: params,
timeout: timeout,
log_lvl: log_lvl
})
.then(function (site_domain_obj_get_result) {
if (site_domain_obj_get_result) {
// slct.site_domain_obj = site_domain_obj_get_result;
// console.log(`site_domain object:`, get(slct).site_domain_obj);
// ae_loc.account_id = $slct.site_domain_obj.account_id_random;
// ae_loc.site_id = $slct.site_domain_obj.site_id_random;
// ae_loc.site_domain_id = $slct.site_domain_obj.site_domain_id_random;
return site_domain_obj_get_result;
} else {
console.log('No results returned.');
return null;
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
});
return ae_promises.load__site_domain_obj;
}
// Updated 2024-03-29
async function handle_load_ae_obj_code__data_store(
{
api_cfg,
code,
data_type = 'text',
for_type = null,
for_id = null,
try_cache = true,
save_idb = false,
timeout = 9000,
log_lvl = 0
}: {
api_cfg: any,
code: string,
data_type?: string,
for_type?: string|null,
for_id?: string|null,
try_cache?: boolean,
save_idb?: boolean,
timeout?: number,
log_lvl?: number
}
) {
if (log_lvl) {
console.log(`*** handle_get_data_store_obj_w_code() *** code=${code}`);
}
if (!code) {
console.log(`*ae_func* No code provided!`);
return false;
}
if (!api_cfg.account_id) {
console.log(`*ae_func* No account_id found in API config!`);
return false;
}
ae_promises.load__data_store_obj = api.get_data_store_obj_w_code({
api_cfg: api_cfg,
data_store_code: code,
data_type: data_type,
timeout: timeout,
log_lvl: log_lvl
})
.then(function (get_ds_result) {
let return_this = null;
if (get_ds_result) {
if (log_lvl) {
console.log(`*ae_func* Got a result for code ${code}`);
}
if (!get_ds_result.data_store_id_random) {
console.log('*ae_func* Something went wrong? No data store ID found.');
return false;
}
// let ae_ds_tmp: key_val = {};
let ds_code_obj =
{
id: null,
account_id: null,
code: code,
name: null,
type: data_type,
for_type: null, // for_type
for_id: null, // for_id
access_read: null, // 'super', 'administrator', 'trusted', 'anonymous'
access_write: null, // 'super', 'administrator', 'trusted', 'anonymous'
access_delete: null, // 'super', 'administrator', 'trusted', 'anonymous'
html: null,
json: null,
md: null,
text: null,
updated_on: null,
chk_account_id: api_cfg.account_id,
loaded_on: new Date().toISOString(),
};
let val_json: key_val;
let val_html: key_val;
let val_md: key_val;
let val_sql: key_val;
let val_text: string;
// Set the loaded_on datetime to the current time for reference later. This will be used to determine if the data store is stale.
// ds_code_obj.loaded_on = new Date().toISOString();
// Set the chk_account_id as a backup check to make sure the data store belongs to the account for the current site. This should not be needed, but here we are...
// ds_code_obj.chk_account_id = api_cfg.account_id;
ds_code_obj.id = get_ds_result.data_store_id_random;
ds_code_obj.account_id = get_ds_result.account_id_random;
ds_code_obj.code = get_ds_result.code; // This will overwrite whatever was passed in.
ds_code_obj.name = get_ds_result.name;
ds_code_obj.type = get_ds_result.type; // This will overwrite whatever was passed in.
if (data_type == 'html') {
ds_code_obj.html = get_ds_result.text;
val_html = get_ds_result.text;
return_this = get_ds_result.html;
} else if (data_type == 'json') {
ds_code_obj.json = get_ds_result.json;
val_json = get_ds_result.json;
return_this = get_ds_result.json;
} else if (data_type == 'md') {
ds_code_obj.text = get_ds_result.text;
val_md = get_ds_result.text;
return_this = get_ds_result.text;
} else if (data_type == 'sql') {
ds_code_obj.text = get_ds_result.text;
val_sql = get_ds_result.text;
return_this = get_ds_result.text;
} else {
ds_code_obj.text = get_ds_result.text;
val_text = get_ds_result.text;
return_this = get_ds_result.text;
}
// if (data_type == 'text') {
// // console.log(get_ds_result.text);
// return_this = get_ds_result.text;
// } else if (data_type == 'json') {
// // console.log(get_ds_result.json);
// return_this = get_ds_result.json;
// }
if (save_idb) {
if (browser) {
let key_prefix = 'ae_ds__';
if (log_lvl) {
console.log(`*ae_func* localStorage key: ${code}, value:`, get_ds_result);
}
localStorage.setItem(`${key_prefix}${code}`, JSON.stringify(get_ds_result));
} else {
if (log_lvl) {
console.log('*ae_func* No browser! Can not use localStorage to save data store object.');
}
}
}
} else {
console.log('*ae_func* No results returned.');
return_this = null;
}
return return_this;
})
.catch(function (error) {
console.log('*ae_func* No results returned or failed.', error);
});
return ae_promises.load__data_store_obj;
}
// Updated 2024-03-27
async function handle_update_ae_obj_id_crud(
{
api_cfg,
object_type,
object_id,
field_name,
new_field_value,
params={},
try_cache=false,
log_lvl=0
}: {
api_cfg: any,
object_type: string,
object_id: string,
field_name: string,
new_field_value: any,
params: any|key_val,
try_cache: boolean,
log_lvl: number
}) {
let patch_result: any = null;
ae_promises.api_update__ae_obj = api.update_ae_obj_id_crud({
api_cfg: api_cfg,
obj_type: object_type,
obj_id: object_id,
field_name: field_name,
field_value: new_field_value,
// fields: data,
key: api_cfg.api_crud_super_key,
// jwt: null,
// params: params,
// data: patch_data,
log_lvl: log_lvl
})
.then(function (results) {
console.log('PATCH Promise', results);
if (results) {
console.log(`Patched - Field Name: ${field_name} with new Field Value: ${new_field_value}`);
patch_result = 'PATCH complete';
} else {
console.log(`Not Patched - Field Name: ${field_name} with new Field Value: ${new_field_value}; Account ID: ${api_cfg.account_id}`);
patch_result = 'PATCH failed';
return false;
}
return true;
})
.catch(function (error) {
console.log('Something went wrong patching the record.');
console.log(error);
return false;
})
.finally(function () {
console.log('PATCH Promise finally');
});
return ae_promises.api_update__ae_obj;
}
async function handle_download_export__obj_type(
{
api_cfg,
get_obj_type, // The type of object to return: event_badge, event_presenter, sponsorship, etc.
for_obj_type, // Usually for an account, event, event_exhibit, or sponsorship_cfg
for_obj_id, // The ID of the object
exp_alt = null, // Export name (idaa, other, not 'default')
file_type = 'CSV', // 'CSV' or 'Excel'
return_file = true,
filename = 'no_filename.csv',
auto_download = false,
limit = 5000,
params = {}, // key value object is expected
log_lvl = 0
}: {
api_cfg: any,
get_obj_type: string,
for_obj_type: string,
for_obj_id: string,
exp_alt?: null|string,
file_type?: string,
return_file?: boolean,
filename?: string,
auto_download?: boolean,
limit?: number,
params?: key_val,
log_lvl?: number
}
) {
console.log('*** ae_core_functions.js: handle_download_export__obj_type() ***');
let task_id = for_obj_id;
const endpoint = `/v2/crud/${get_obj_type}/list`;
params['for_obj_type'] = for_obj_type;
params['for_obj_id'] = for_obj_id;
if (file_type == 'CSV' || file_type == 'Excel') {
params['file_type'] = file_type;
}
params['return_file'] = true;
params['mdl_alt'] = 'out';
if (exp_alt) {
params['exp_alt'] = exp_alt;
}
// let clean_filename = filename.replace(/[^a-z0-9]/gi, '_');
// let clean_filename = filename.replace(/[^a-z0-9\[\]-]/gi, '_');
let clean_filename = filename.replace(/[^a-zA-Z0-9\[\]-_.]/gi, '_');
// let clean_filename = filename.replace(/[^a-zA-Z0-9\[\]-\._ ]/gi, '_');
if (limit >= 0) {
params['limit'] = limit;
}
ae_promises.download__export_file = await api.get_object({
api_cfg: api_cfg,
endpoint: endpoint,
params: params,
timeout: 90000, // Seems to timeout sometimes with the default of 60 seconds
return_blob: return_file,
filename: clean_filename,
auto_download: auto_download,
task_id: task_id,
log_lvl: log_lvl
});
console.log('ae_promises.download__export_file:', ae_promises.download__export_file);
return ae_promises.download__export_file;
}
let export_obj = {
check_hosted_file_obj_w_hash: check_hosted_file_obj_w_hash,
handle_load_ae_obj_id__site_domain: handle_load_ae_obj_id__site_domain,
handle_load_ae_obj_code__data_store: handle_load_ae_obj_code__data_store,
handle_load_ae_obj_id__person: handle_load_ae_obj_id__person,
handle_load_ae_obj_li__person: handle_load_ae_obj_li__person,
handle_create_ae_obj__person: handle_create_ae_obj__person,
handle_update_ae_obj__person: handle_update_ae_obj__person,
handle_update_ae_obj_id_crud: handle_update_ae_obj_id_crud,
handle_download_export__obj_type: handle_download_export__obj_type,
generate_qr_code: generate_qr_code
};
export let core_func = export_obj;

613
src/lib/ae_events__event.ts Normal file
View File

@@ -0,0 +1,613 @@
import type { key_val } from '$lib/ae_stores';
import { api } from '$lib/api';
import { db_events } from "$lib/db_events";
let ae_promises: key_val = {};
// Updated 2024-09-25
export async function load_ae_obj_id__event(
{
api_cfg,
event_id,
inc_file_li = false,
inc_location_li = false,
inc_presentation_li = false,
inc_presenter_li = false,
inc_session_li = false,
try_cache = true,
log_lvl = 0
}: {
api_cfg: any,
event_id: string,
inc_file_li?: boolean,
inc_location_li?: boolean,
inc_presentation_li?: boolean,
inc_presenter_li?: boolean,
inc_session_li?: boolean,
try_cache?: boolean,
log_lvl?: number
}
) {
console.log(`*** load_ae_obj_id__event() *** event_id=${event_id}`);
let params = {};
// $events_sess.badges.status_load__event_obj = 'loading';
ae_promises.load__event_obj = await api.get_ae_obj_id_crud({
api_cfg: api_cfg,
obj_type: 'event',
obj_id: event_id, // NOTE: This is the FQDN, not normally the ID.
use_alt_table: true, // NOTE: This will use the table_name_alt value instead of the table_name value in the API config.
use_alt_base: false, // NOTE: This will use the base_name_alt value instead of the base_name value in the API config.
params: params,
log_lvl: log_lvl
})
.then(function (event_obj_get_result) {
if (event_obj_get_result) {
if (try_cache) {
// This is expecting a list
db_save_ae_obj_li__event({
obj_type: 'event',
obj_li: [event_obj_get_result]
});
}
return event_obj_get_result;
} else {
console.log('No results returned.');
return null;
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
});
return ae_promises.load__event_obj;
}
// Updated 2024-09-27
export async function load_ae_obj_li__event(
{
api_cfg,
for_obj_type = 'account',
for_obj_id,
qry_conference = true,
qry_str = null,
inc_file_li = false,
inc_location_li = false,
inc_presentation_li = false,
inc_presenter_li = false,
inc_session_li = false,
order_by_li = {'start_datetime': 'DESC', 'name': 'ASC', 'updated_on': 'DESC', 'created_on': 'DESC'},
params_json = null,
params = {},
try_cache = true,
log_lvl = 0
}: {
api_cfg: any,
for_obj_type: string,
for_obj_id: string,
qry_conference?: null|boolean,
qry_str?: null|string,
inc_file_li?: boolean,
inc_location_li?: boolean,
inc_presentation_li?: boolean,
inc_presenter_li?: boolean,
inc_session_li?: boolean,
order_by_li?: key_val,
params_json?: null|key_val,
params?: key_val,
try_cache?: boolean,
log_lvl?: number
}
) {
console.log(`*** load_ae_obj_li__event() *** for_obj_id=${for_obj_id}`);
let enabled: string = (params.qry__enabled ?? 'enabled'); // all, disabled, enabled
let hidden: string = (params.qry__hidden ?? 'not_hidden'); // all, hidden, not_hidden
let limit: number = (params.qry__limit ?? 99); // 99
let offset: number = (params.qry__offset ?? 0); // 0
// There is probably a better way to handle this. I don't want to just start a new object if it is not passed. However, the qry_conference and qry_str are sort of a special case. -2024-10-01
if (!params_json) {
params_json = {};
}
if (qry_conference) {
if (!params_json['and_qry']) {
params_json['and_qry'] = {};
}
params_json['and_qry']['conference'] = qry_conference;
} else if (qry_conference === false) {
if (!params_json['and_qry']) {
params_json['and_qry'] = {};
}
console.log('qry_conference is false!');
params_json['and_qry']['conference'] = qry_conference;
}
if (qry_str) {
if (!params_json['ft_qry']) {
params_json['ft_qry'] = {};
}
params_json['ft_qry'] = {};
params_json['ft_qry']['default_qry_str'] = qry_str;
params_json['ft_qry']['location_address_json_ext'] = qry_str;
params_json['ft_qry']['contact_li_json_ext'] = qry_str;
}
// console.log('params_json:', params_json);
// ae_promises.load__event_obj_li = await api.get_ae_obj_li_for_obj_id_crud({
// api_cfg: api_cfg,
// obj_type: 'event',
// for_obj_type: for_obj_type,
// for_obj_id: for_obj_id,
// use_alt_table: true, // NOTE: This will use the table_name_alt value instead of the table_name value in the API config.
// use_alt_base: false, // NOTE: This will use the base_name_alt value instead of the base_name value
// enabled: enabled,
// hidden: hidden,
// order_by_li: order_by_li,
// limit: limit,
// offset: offset,
// params_json: params_json,
// params: params,
// log_lvl: log_lvl
// })
ae_promises.load__event_obj_li = await api.get_ae_obj_li_for_obj_id_crud_v2({
api_cfg: api_cfg,
obj_type: 'event',
for_obj_type: for_obj_type,
for_obj_id: for_obj_id,
use_alt_tbl: true, // NOTE: This will use the table_name_alt value instead of the table_name value in the API config.
// use_alt_mdl: false, // NOTE: This will use the base_name_alt value instead of the base_name value
enabled: enabled,
hidden: hidden,
order_by_li: order_by_li,
limit: limit,
offset: offset,
params_json: params_json,
params: params,
log_lvl: log_lvl
})
.then(function (event_obj_li_get_result) {
if (event_obj_li_get_result) {
if (try_cache) {
db_save_ae_obj_li__event({obj_type: 'event', obj_li: event_obj_li_get_result});
}
return event_obj_li_get_result;
} else {
return [];
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
});
if (log_lvl) {
console.log('ae_promises.load__event_obj_li:', ae_promises.load__event_obj_li);
}
return ae_promises.load__event_obj_li;
}
// The qry_ae_obj_li__event() is essentially a wrapper for the load_ae_obj_li__event() function. This should process the query strings and related before calling the load_ae_obj_li__event() function.
// Updated 2024-10-01
export async function qry_ae_obj_li__event(
{
api_cfg,
for_obj_type = 'account',
for_obj_id,
qry_conference = true,
qry_physical = null,
qry_virtual = null,
qry_type = null,
qry_str = null,
inc_file_li = false,
inc_location_li = false,
inc_presentation_li = false,
inc_presenter_li = false,
inc_session_li = false,
order_by_li = {'start_datetime': 'DESC', 'name': 'ASC', 'updated_on': 'DESC', 'created_on': 'DESC'},
params = {},
try_cache = true,
log_lvl = 0
}: {
api_cfg: any,
for_obj_type: string,
for_obj_id: string,
qry_conference?: null|boolean,
qry_physical?: null|boolean,
qry_virtual?: null|boolean,
qry_type?: null|string,
qry_str?: null|string,
inc_file_li?: boolean,
inc_location_li?: boolean,
inc_presentation_li?: boolean,
inc_presenter_li?: boolean,
inc_session_li?: boolean,
order_by_li?: key_val,
params?: key_val,
try_cache?: boolean,
log_lvl?: number
}
) {
console.log(`*** qry_ae_obj_li__event() *** for_obj_id=${for_obj_id}`);
let enabled: string = (params.qry__enabled ?? 'enabled'); // all, disabled, enabled
let hidden: string = (params.qry__hidden ?? 'not_hidden'); // all, hidden, not_hidden
let limit: number = (params.qry__limit ?? 99); // 99
let offset: number = (params.qry__offset ?? 0); // 0
// Build the params_json object. This needs to be documented better! -2024-10-01
let params_json: key_val = {};
params_json['and_qry'] = {};
// This is handled in the actual load_ae_obj_li__event() function. For now...?
// if (qry_conference) {
// params_json['and_qry']['conference'] = qry_conference;
// } else if (qry_conference === false) {
// console.log('qry_conference is false!');
// params_json['and_qry']['conference'] = qry_conference;
// }
if (qry_physical && qry_virtual) {
// Ignore both if both are set to true.
} else if (qry_physical || qry_virtual) {
if (qry_physical) {
params_json['and_qry']['physical'] = qry_physical;
}
if (qry_virtual) {
params_json['and_qry']['virtual'] = qry_virtual;
}
}
if (qry_type) {
params_json['and_qry']['type'] = qry_type;
}
if (qry_str) {
params_json['ft_qry'] = {};
params_json['ft_qry']['default_qry_str'] = qry_str;
params_json['ft_qry']['location_address_json_ext'] = qry_str;
params_json['ft_qry']['contact_li_json_ext'] = qry_str;
}
if (log_lvl) {
console.log('params_json:', params_json);
}
ae_promises.qry__event_obj_li = await load_ae_obj_li__event({
api_cfg: api_cfg,
for_obj_type: for_obj_type,
for_obj_id: for_obj_id,
qry_conference: qry_conference,
qry_str: qry_str,
inc_file_li: inc_file_li,
inc_location_li: inc_location_li,
inc_presentation_li: inc_presentation_li,
inc_presenter_li: inc_presenter_li,
inc_session_li: inc_session_li,
order_by_li: order_by_li,
params_json: params_json,
params: params,
try_cache: try_cache,
log_lvl: log_lvl
});
return ae_promises.qry__event_obj_li;
}
// Updated 2024-09-25
export async function create_ae_obj__event(
{
api_cfg,
account_id,
data_kv,
params={},
log_lvl=0
}: {
api_cfg: any,
account_id: string,
data_kv: key_val,
params?: key_val,
log_lvl?: number
}
) {
console.log(`*** create_ae_obj__event() *** account_id=${account_id}`);
ae_promises.create__event = await api.create_ae_obj_crud({
api_cfg: api_cfg,
obj_type: 'event',
fields: {
account_id_random: account_id,
...data_kv
},
key: api_cfg.api_crud_super_key,
params: params,
return_obj: true,
log_lvl: log_lvl
})
.then(function (event_obj_create_result) {
if (event_obj_create_result) {
db_save_ae_obj_li__event(
{
obj_type: 'event',
obj_li: [event_obj_create_result]
});
return event_obj_create_result;
} else {
return null;
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
})
.finally(function () {
});
if (log_lvl) {
console.log('ae_promises.create__event:', ae_promises.create__event);
}
return ae_promises.create__event;
}
// Updated 2024-09-25
export async function update_ae_obj__event(
{
api_cfg,
event_id,
data_kv,
params = {},
try_cache = true,
log_lvl = 0
}: {
api_cfg: any,
event_id: string,
data_kv: key_val,
params?: key_val,
try_cache?: boolean,
log_lvl?: number
}
) {
if (log_lvl) {
console.log(`*** update_ae_obj__event() *** event_id=${event_id}`, data_kv);
}
// ae_promises.update__event_obj = 'test';
ae_promises.update__event_obj = await api.update_ae_obj_id_crud({
api_cfg: api_cfg,
obj_type: 'event',
obj_id: event_id,
fields: data_kv,
key: api_cfg.api_crud_super_key,
params: params,
return_obj: true,
log_lvl: log_lvl
})
.then(function (event_obj_update_result) {
if (event_obj_update_result) {
if (try_cache) {
db_save_ae_obj_li__event({
obj_type: 'event', obj_li: [event_obj_update_result]
});
}
return event_obj_update_result;
} else {
return null;
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
})
.finally(function () {
});
if (log_lvl) {
console.log('ae_promises.update__event_obj:', ae_promises.update__event_obj);
}
return ae_promises.update__event_obj;
}
// This function will loop through the event_obj_li and save each one to the DB.
export function db_save_ae_obj_li__event(
{
obj_type,
obj_li,
log_lvl = 0
}: {
obj_type: string,
obj_li: any,
log_lvl?: number
}
) {
if (log_lvl) {
console.log(`*** db_save_ae_obj_li__event() ***`);
}
if (obj_li && obj_li.length) {
obj_li.forEach(async function (obj: any) {
if (log_lvl) {
console.log(`ae_obj ${obj_type}:`, obj);
}
try {
const id_random = await db_events.events.put({
id: obj.event_id_random,
// id_random: obj.event_id_random,
event_id: obj.event_id_random,
event_id_random: obj.event_id_random,
code: obj.event_code,
account_id: obj.account_id_random,
account_id_random: obj.account_id_random,
conference: obj.conference,
type: obj.type,
name: obj.name,
summary: obj.summary,
description: obj.description,
start_datetime: obj.start_datetime,
end_datetime: obj.end_datetime,
timezone: obj.timezone,
location_address_json: obj.location_address_json,
mod_abstracts_json: obj.mod_abstracts_json,
mod_badges_json: obj.mod_badges_json,
mod_exhibits_json: obj.mod_exhibits_json,
mod_pres_mgmt_json: obj.mod_pres_mgmt_json,
cfg_json: obj.cfg_json,
enable: obj.enable,
hide: obj.hide,
priority: obj.priority,
sort: obj.sort,
group: obj.group,
notes: obj.notes,
created_on: obj.created_on,
updated_on: obj.updated_on,
// IDAA Recovery Meetings
contact_li_json: obj.contact_li_json,
external_person_id: obj.external_person_id,
physical: obj.physical,
virtual: obj.virtual,
weekday_sunday: obj.weekday_sunday,
weekday_monday: obj.weekday_monday,
weekday_tuesday: obj.weekday_tuesday,
weekday_wednesday: obj.weekday_wednesday,
weekday_thursday: obj.weekday_thursday,
weekday_friday: obj.weekday_friday,
weekday_saturday: obj.weekday_saturday,
recurring_start_time: obj.recurring_start_time,
// From SQL view
file_count: obj.file_count,
file_count_all: obj.file_count_all,
internal_use_count: obj.internal_use_count,
event_file_id_li_json: obj.event_file_id_li_json,
});
// console.log(`Put obj with ID: ${obj.event_id_random} or ${id_random}`);
} catch (error) {
let status = `Failed to put ${obj.event_id_random}: ${error}`;
console.log(status);
}
// const id_random = await db_events.events.put(obj);
// console.log(`Put obj with ID: ${obj.event_id_random}`);
});
return true;
}
}
// This function will process the event config, specifically for presentation management.
export function sync_config__event_pres_mgmt(
{
pres_mgmt_cfg_remote, // This is the remote config that will be compared.
pres_mgmt_cfg_local, // This is the local config that will be updated.
log_lvl = 0
}: {
pres_mgmt_cfg_remote: key_val,
pres_mgmt_cfg_local: key_val,
log_lvl?: number
}
) {
if (log_lvl) {
console.log(`*** sync_config__event_pres_mgmt() *** pres_mgmt_cfg_remote:`, pres_mgmt_cfg_remote);
}
// Deal with things that can not be overridden first:
// Labels:
pres_mgmt_cfg_local.label__presenter_external_id = pres_mgmt_cfg_remote?.label__presenter_external_id ?? 'External ID';
pres_mgmt_cfg_local.label__session_poc_type = pres_mgmt_cfg_remote?.label__session_poc_type ?? 'poc';
pres_mgmt_cfg_local.label__session_poc_name = pres_mgmt_cfg_remote?.label__session_poc_name_short ?? 'POC';
pres_mgmt_cfg_local.label__session_poc_name = pres_mgmt_cfg_remote?.label__session_poc_name ?? 'Point of Contact';
// Hide content:
pres_mgmt_cfg_local.hide__session_poc = pres_mgmt_cfg_remote?.hide__session_poc ?? false;
// pres_mgmt_cfg_local.hide__report_kv = pres_mgmt_cfg_remote?.hide__report_kv ?? null;
// pres_mgmt_cfg_local.limit__navigation = pres_mgmt_cfg_remote?.limit__navigation ?? false;
// pres_mgmt_cfg_local.limit__options = pres_mgmt_cfg_remote?.limit__options ?? false;
// Required fields or options (agreements):
pres_mgmt_cfg_local.require__presenter_agree = pres_mgmt_cfg_remote?.require__presenter_agree ?? false; // In use
pres_mgmt_cfg_local.require__session_agree = pres_mgmt_cfg_remote?.require__session_agree ?? false; // New and in progress
// Show content:
// pres_mgmt_cfg_local.show__navigation = pres_mgmt_cfg_remote?.show__navigation ?? false;
pres_mgmt_cfg_local.file_purpose_option_kv = pres_mgmt_cfg_remote?.file_purpose_option_kv ?? null;
// Deal with things that can be overridden:
// Locking the config is targeted at the trusted staff level and below. It is more or less ignored at the global manager and super levels. It may be enforced at the staff admin level?
// pres_mgmt_cfg_local.lock_config = pres_mgmt_cfg_remote?.lock_config ? true : false; // This disables the sync local config button and options.
if (pres_mgmt_cfg_local.lock_config) {
console.log(`The config should be locked! Forcing the sync!`);
// This is to forcibly sync the local config with the remote config.
pres_mgmt_cfg_local.sync_local_config = true;
} else {
// Do not override the preference for syncing the local config with the remote config.
console.log(`The config is not locked. Currently set to sync? ${pres_mgmt_cfg_local.sync_local_config}`);
// Check if the sync_local_config is undefined versus just false.
// if (pres_mgmt_cfg_local?.sync_local_config) {
// pres_mgmt_cfg_local.sync_local_config = true;
// } else {
// pres_mgmt_cfg_local.sync_local_config = pres_mgmt_cfg_remote?.sync_local_config ?? false;
// }
}
if (pres_mgmt_cfg_local?.sync_local_config) {
if (log_lvl) {
console.log(`Syncing the local config with the remote config!!!`);
}
// Hide content:
pres_mgmt_cfg_local.hide__location_code = pres_mgmt_cfg_remote?.hide__location_code ?? false;
pres_mgmt_cfg_local.hide__presentation_code = pres_mgmt_cfg_remote?.hide__presentation_code ?? false;
pres_mgmt_cfg_local.hide__presenter_code = pres_mgmt_cfg_remote?.hide__presenter_code ?? false;
pres_mgmt_cfg_local.hide__presenter_biography = pres_mgmt_cfg_remote?.hide__presenter_biography ?? false;
pres_mgmt_cfg_local.hide__session_code = pres_mgmt_cfg_remote?.hide__session_code ?? false;
pres_mgmt_cfg_local.hide__session_description = pres_mgmt_cfg_remote?.hide__session_description ?? false;
pres_mgmt_cfg_local.hide__session_location = pres_mgmt_cfg_remote?.hide__session_location ?? false;
pres_mgmt_cfg_local.hide__session_msg = pres_mgmt_cfg_remote?.hide__session_msg ?? false;
// pres_mgmt_cfg_local.hide__session_li_poc_field = pres_mgmt_cfg_remote?.hide__session_li_poc_field ?? false; // This should still allow the POC name to be shown.
pres_mgmt_cfg_local.hide__session_poc_profile = pres_mgmt_cfg_remote?.hide__session_poc_profile ?? false; // This should still allow the POC name to be shown.
pres_mgmt_cfg_local.hide__session_poc_biography = pres_mgmt_cfg_remote?.hide__session_poc_biography ?? false; // New and in progress
pres_mgmt_cfg_local.hide__session_poc_profile_pic = pres_mgmt_cfg_remote?.hide__session_poc_profile_pic ?? false; // New and in progress
pres_mgmt_cfg_local.show__copy_access_link = pres_mgmt_cfg_remote?.show__copy_access_link ?? false;
pres_mgmt_cfg_local.show__email_access_link = pres_mgmt_cfg_remote?.show__email_access_link ?? false;
pres_mgmt_cfg_local.show__launcher_link = pres_mgmt_cfg_remote?.show__launcher_link ?? false;
pres_mgmt_cfg_local.show__launcher_link_legacy = pres_mgmt_cfg_remote?.show__launcher_link_legacy ?? false;
}
if (log_lvl) {
console.log(`pres_mgmt_cfg_local:`, pres_mgmt_cfg_local);
}
return pres_mgmt_cfg_local;
}

View File

@@ -0,0 +1,353 @@
import type { key_val } from '$lib/ae_stores';
import { api } from '$lib/api';
import { db_events } from "$lib/db_events";
let ae_promises: key_val = {};
// Updated 2024-03
export async function handle_load_ae_obj_id__badge(
{
api_cfg,
badge_id,
try_cache=false,
log_lvl=0
}: {
api_cfg: any,
badge_id: string,
try_cache?: boolean,
log_lvl?: number
}
) {
console.log(`*** handle_load_ae_obj_id__badge() *** badge_id=${badge_id}`);
let params = {};
// $events_sess.badges.status_load__badge_obj = 'loading';
ae_promises.load__badge_obj = await api.get_ae_obj_id_crud({
api_cfg: api_cfg,
obj_type: 'event_badge',
obj_id: badge_id, // NOTE: This is the FQDN, not normally the ID.
use_alt_table: false, // NOTE: This will use the table_name_alt value instead of the table_name value in the API config.
use_alt_base: false, // NOTE: This will use the base_name_alt value instead of the base_name value in the API config.
params: params,
log_lvl: 0
})
.then(function (badge_obj_get_result) {
if (badge_obj_get_result) {
// This is expecting a list
handle_db_save_ae_obj_li__badge({obj_type: 'event_badge', obj_li: [badge_obj_get_result]});
return badge_obj_get_result;
} else {
console.log('No results returned.');
return null;
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
});
return ae_promises.load__badge_obj;
}
// Updated 2024-03-06
export async function handle_load_ae_obj_li__badge(
{
api_cfg,
event_id,
params={},
try_cache=true,
log_lvl=0
}: {
api_cfg: any,
event_id: any,
params: any,
try_cache?: boolean,
log_lvl: number
}) {
console.log(`*** handle_load_ae_obj_li__badge() *** event_id=${event_id}`);
let fulltext_search_qry_str = ''; // $events_sess.badges.fulltext_search_qry_str;
let enabled: string = (params.qry__enabled ?? 'enabled'); // all, disabled, enabled
let hidden: string = (params.qry__hidden ?? 'not_hidden'); // all, hidden, not_hidden
let limit: number = (params.qry__limit ?? 99); // 99
let offset: number = (params.qry__offset ?? 0); // 0
let params_json: key_val = {};
if (fulltext_search_qry_str && fulltext_search_qry_str.length > 2) {
params_json['ft_qry'] = {
'default_qry_str': fulltext_search_qry_str,
// 'location_address_json_ext': fulltext_search_qry_str, // JSON extracted text DB field
// 'contact_li_json_ext': fulltext_search_qry_str, // JSON extracted text DB field
};
}
// console.log('params_json:', params_json);
// console.log(params_json);
// $events_sess.badges.status_qry__search = 'loading';
ae_promises.load__event_badge_obj_li = await api.get_ae_obj_li_for_obj_id_crud({
api_cfg: api_cfg,
obj_type: 'event_badge',
for_obj_type: 'event',
for_obj_id: event_id,
use_alt_table: false, // NOTE: This will use the table_name_alt value instead of the table_name value in the API config.
use_alt_base: false, // NOTE: This will use the base_name_alt value instead of the base_name value in the API config.
enabled: enabled,
hidden: hidden,
order_by_li: {'priority': 'DESC', 'sort': 'DESC', 'updated_on': 'DESC', 'created_on': 'DESC'},
// order_by_li: {'priority': 'DESC', 'sort': 'DESC', 'created_on': 'DESC', 'updated_on': 'DESC'},
limit: limit,
offset: offset,
params_json: params_json,
params: params,
log_lvl: log_lvl
})
.then(function (badge_obj_li_get_result) {
// console.log('Badge list:', badge_obj_li_get_result);
if (badge_obj_li_get_result) {
// $slct.badge_obj_li = badge_obj_li_get_result;
handle_db_save_ae_obj_li__badge({obj_type: 'event_badge', obj_li: badge_obj_li_get_result});
return badge_obj_li_get_result;
} else {
// $slct.badge_obj_li = [];
return [];
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
})
.finally(function () {
// $events_sess.badges.status_qry__search = 'done';
// console.log('Badge list:', badge_obj_li_get_result);
// return badge_obj_li_get_result;
});
if (log_lvl) {
console.log('ae_promises.load__event_badge_obj_li:', ae_promises.load__event_badge_obj_li);
}
return ae_promises.load__event_badge_obj_li;
}
export async function handle_search__event_badge(
{
api_cfg,
event_id,
type_code = null,
fulltext_search_qry_str,
like_search_qry_str = null,
external_event_id,
params = {},
try_cache = true,
log_lvl = 0
}: {
api_cfg: any,
event_id: any,
type_code: any,
fulltext_search_qry_str: any,
like_search_qry_str: any,
external_event_id: any,
params: any,
try_cache: boolean,
log_lvl: number
}
) {
console.log(`*** handle_search__event_badge() *** event_id=${event_id}`);
let enabled: string = (params.qry__enabled ?? 'enabled'); // all, disabled, enabled
let hidden: string = (params.qry__hidden ?? 'not_hidden'); // all, hidden, not_hidden
let limit: number = (params.qry__limit ?? 25); // 99
let offset: number = (params.qry__offset ?? 0); // 0
let params_json: key_val = {};
if (!fulltext_search_qry_str && !like_search_qry_str) {
console.log('No search string provided!!!');
return false; // Returning false instead of [] because no search was performed.
}
if (fulltext_search_qry_str && fulltext_search_qry_str.length > 2) {
params_json['ft_qry'] = {
'default_qry_str': fulltext_search_qry_str,
// 'location_address_json_ext': fulltext_search_qry_str, // JSON extracted text DB field
// 'contact_li_json_ext': fulltext_search_qry_str, // JSON extracted text DB field
};
}
if (like_search_qry_str && like_search_qry_str.length > 2) {
// Old Python version that needs to be in JS
// # Strip (left right) whitespace then commas then semicolons
// query_str = query_str.strip().strip(',').strip(';')
// # Replace commas, semicolons, and then spaces with %
// query_str_like = query_str.replace(',', ' ').replace(';', ' ').replace(' ', '%').replace(' ', '%')
// # data['query_str'] = f'%{query_str}%'
// log.debug(query_str_like)
// data['query_str'] = f'%{query_str_like}%'
// let like_search_qry_str_new = like_search_qry_str.trim().replace(',', ' ').replace(';', ' ').replace(' ', '%').replace(' ', '%');
// like_search_qry_str_new = `%${like_search_qry_str_new}%`;
// console.log('like_search_qry_str_new:', like_search_qry_str_new);
params_json['and_like'] = {
'default_qry_str': like_search_qry_str,
};
}
params_json['and_qry'] = {};
if (external_event_id) {
params_json['and_qry']['external_event_id'] = external_event_id;
}
if (type_code) { // This is the event_badge.badge_type_code. There is also a member_type_code and registration_type_code that could be referenced in the future.
params_json['and_qry']['badge_type_code'] = type_code;
}
let order_by_li = {'print_count': 'ASC', 'priority': 'DESC', 'sort': 'DESC', 'given_name': 'ASC', 'family_name': 'ASC', 'updated_on': 'DESC', 'created_on': 'DESC'};
// $events_sess.badges.status_qry__search = 'loading';
ae_promises.search__event_badge = await api.get_ae_obj_li_for_obj_id_crud({
api_cfg: api_cfg,
obj_type: 'event_badge',
for_obj_type: 'event',
for_obj_id: event_id,
use_alt_table: false, // NOTE: This will use the table_name_alt value instead of the table_name value in the API config.
use_alt_base: false, // NOTE: This will use the base_name_alt value instead of the base_name value in the API config.
enabled: enabled,
hidden: hidden,
order_by_li: order_by_li,
// order_by_li: {'priority': 'DESC', 'sort': 'DESC', 'created_on': 'DESC', 'updated_on': 'DESC'},
limit: limit,
offset: offset,
params_json: params_json,
params: params,
log_lvl: log_lvl
})
.then(function (badge_obj_li_get_result) {
// console.log('Badge list:', badge_obj_li_get_result);
if (badge_obj_li_get_result) {
// $slct.badge_obj_li = badge_obj_li_get_result;
handle_db_save_ae_obj_li__badge({obj_type: 'event_badge', obj_li: badge_obj_li_get_result});
return badge_obj_li_get_result;
} else {
// $slct.badge_obj_li = [];
return [];
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
})
.finally(function () {
// $events_sess.badges.status_qry__search = 'done';
// console.log('Badge list:', badge_obj_li_get_result);
// return badge_obj_li_get_result;
});
if (log_lvl) {
console.log('ae_promises.search__event_badge:', ae_promises.search__event_badge);
}
return ae_promises.search__event_badge;
}
// This function will loop through the badge_obj_li and save each one to the DB.
export function handle_db_save_ae_obj_li__badge(
{
obj_type,
obj_li,
log_lvl = 0
}: {
obj_type: string,
obj_li: any,
log_lvl?: number
}
) {
if (log_lvl) {
console.log(`*** handle_db_save_ae_obj_li__badge() ***`);
}
if (obj_li && obj_li.length) {
obj_li.forEach(async function (obj: any) {
if (log_lvl) {
console.log(`ae_obj ${obj_type}:`, obj);
}
try {
const id_random = await db_events.badges.put({
id_random: obj.event_badge_id_random,
event_badge_id_random: obj.event_badge_id_random,
event_id_random: obj.event_id_random,
pronouns: obj.pronouns,
informal_name: obj.informal_name,
title_names: obj.title_names,
given_name: obj.given_name,
middle_name: obj.middle_name,
family_name: obj.family_name,
designations: obj.designations,
professional_title: obj.professional_title,
professional_title_override: obj.professional_title_override,
full_name: obj.full_name,
full_name_override: obj.full_name_override,
affiliations: obj.affiliations,
affiliations_override: obj.affiliations_override,
email: obj.email,
email_override: obj.email_override,
address_line_1: obj.address_line_1,
address_line_2: obj.address_line_2,
address_line_3: obj.address_line_3,
city: obj.city,
country_subdivision_code: obj.country_subdivision_code,
state_province: obj.state_province,
state_province_abb: obj.state_province_abb,
postal_code: obj.postal_code,
country_alpha_2_code: obj.country_alpha_2_code,
country: obj.country,
full_address: obj.full_address,
location: obj.location,
location_override: obj.location_override,
query_str: obj.query_str,
badge_type: obj.badge_type,
badge_type_code: obj.badge_type_code,
badge_type_override: obj.badge_type_override,
badge_type_code_override: obj.badge_type_code_override,
external_event_id: obj.external_event_id,
external_id: obj.external_id,
external_person_id: obj.external_person_id,
enable: obj.enable,
hide: obj.hide,
priority: obj.priority,
sort: obj.sort,
group: obj.group,
notes: obj.notes,
created_on: obj.created_on,
updated_on: obj.updated_on,
});
// console.log(`Put obj with ID: ${obj.event_badge_id_random} or ${id_random}`);
} catch (error) {
let status = `Failed to put ${obj.event_badge_id_random}: ${error}`;
console.log(status);
}
// const id_random = await db_events.badges.put(obj);
// console.log(`Put obj with ID: ${obj.event_badge_id_random}`);
});
return true;
}
}

View File

@@ -0,0 +1,584 @@
import type { key_val } from '$lib/ae_stores';
import { api } from '$lib/api';
import { db_events } from "$lib/db_events";
let ae_promises: key_val = {};
// Updated 2024-06-14
export async function load_ae_obj_id__event_file(
{
api_cfg,
event_file_id,
try_cache = false,
log_lvl = 0
}: {
api_cfg: any,
event_file_id: string,
try_cache?: boolean,
log_lvl?: number
}
) {
console.log(`*** load_ae_obj_id__event_file() *** event_file_id=${event_file_id}`);
let params = {};
ae_promises.load__event_file_obj = await api.get_ae_obj_id_crud({
api_cfg: api_cfg,
obj_type: 'event_file',
obj_id: event_file_id, // NOTE: This is the FQDN, not normally the ID.
use_alt_table: false, // NOTE: This will use the table_name_alt value instead of the table_name value in the API config.
use_alt_base: false, // NOTE: This will use the base_name_alt value instead of the base_name value
params: params,
log_lvl: log_lvl
})
.then(function (event_file_obj_get_result) {
if (event_file_obj_get_result) {
// This is expecting a list
db_save_ae_obj_li__event_file({obj_type: 'event_file', obj_li: [event_file_obj_get_result]});
return event_file_obj_get_result;
} else {
console.log('No results returned.');
return null;
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
});
return ae_promises.load__event_file_obj;
}
// Updated 2024-07-03
export async function load_ae_obj_li__event_file(
{
api_cfg,
for_obj_type,
for_obj_id,
params = {},
try_cache = true,
log_lvl = 0
}: {
api_cfg: any,
for_obj_type: string,
for_obj_id: string,
params?: key_val,
try_cache?: boolean,
log_lvl?: number
}
) {
console.log(`*** load_ae_obj_li__event_file() *** for_obj_type=${for_obj_type} for_obj_id=${for_obj_id}`);
// Check if for_obj_type is in the list of valid Aether object types:
let valid_for_obj_types = ['event', 'event_session', 'event_presentation', 'event_presenter', 'event_location'];
if (!valid_for_obj_types.includes(for_obj_type)) {
console.log(`Invalid for_obj_type: ${for_obj_type}`);
return [];
}
let enabled: string = (params.qry__enabled ?? 'enabled'); // all, disabled, enabled
let hidden: string = (params.qry__hidden ?? 'all'); // all, hidden, not_hidden
let limit: number = (params.qry__limit ?? 99); // 99
let offset: number = (params.qry__offset ?? 0); // 0
let params_json: key_val = {};
// console.log('params_json:', params_json);
ae_promises.load__event_file_obj_li = await api.get_ae_obj_li_for_obj_id_crud({
api_cfg: api_cfg,
obj_type: 'event_file',
for_obj_type: for_obj_type,
for_obj_id: for_obj_id,
use_alt_table: true, // NOTE: This will use the table_name_alt value instead of the table_name value in the API config.
use_alt_base: false, // NOTE: This will use the base_name_alt value instead of the base_name value
enabled: enabled,
hidden: hidden,
order_by_li: {'priority': 'DESC', 'sort': 'DESC', 'updated_on': 'DESC', 'created_on': 'DESC'},
limit: limit,
offset: offset,
params_json: params_json,
params: params,
log_lvl: log_lvl
})
.then(function (event_file_obj_li_get_result) {
if (event_file_obj_li_get_result) {
if (try_cache) {
db_save_ae_obj_li__event_file({obj_type: 'event_file', obj_li: event_file_obj_li_get_result});
}
return event_file_obj_li_get_result;
} else {
console.log('No results returned.');
return [];
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
});
if (log_lvl) {
console.log('ae_promises.load__event_file_obj_li:', ae_promises.load__event_file_obj_li);
}
return ae_promises.load__event_file_obj_li;
}
// Updated 2024-06-17
export async function delete_ae_obj_id__event_file(
{
api_cfg,
event_file_id,
params = {},
log_lvl = 0
}: {
api_cfg: any,
event_file_id: string,
params?: key_val,
log_lvl?: number
}
) {
console.log(`*** delete_ae_obj_id__event_file() *** event_file_id=${event_file_id}`);
const endpoint = `/event/file/${event_file_id}/v2`;
params['delete_hosted_file'] = true; // This does not actually delete the hosted file from the server.
params['rm_orphan'] = true; // This is what actually allows the hosted file to be deleted from the server.
ae_promises.delete__event_file_obj = await api.delete_object({
api_cfg: api_cfg,
endpoint: endpoint,
params: params,
// return_meta: return_meta,
log_lvl: log_lvl
});
db_events.files.delete(event_file_id);
return ae_promises.delete__event_file_obj;
}
// Updated 2024-06-14
export async function create_event_file_obj_from_hosted_file_async(
{
api_cfg,
hosted_file_id,
params = {},
data = {},
return_obj = false,
inc_hosted_file = false,
return_meta = false,
log_lvl = 0
}: {
api_cfg: any,
hosted_file_id: string,
params?: key_val,
data?: key_val,
return_obj?: boolean,
inc_hosted_file?: boolean,
return_meta?: boolean,
log_lvl?: number
}
) {
console.log('*** ae_events_functions.js: create_event_file_obj_from_hosted_file() ***');
let endpoint = `/event/file/from_hosted_file/${hosted_file_id}`;
if (return_obj) {
params['return_obj'] = true;
}
if (inc_hosted_file) {
params['inc_hosted_file'] = true;
}
let event_file_obj_post_promise = await api.post_object({
api_cfg: api_cfg,
endpoint: endpoint,
params: params,
data: data,
// return_obj: return_obj,
return_meta: return_meta,
log_lvl: log_lvl
})
.then(function (result) {
console.log('POST DONE create_event_file_obj_from_hosted_file');
console.log(result);
return result;
})
.catch(function (error) {
console.log(error);
return false; // Returning false since something may have gone wrong. Also more in line with what the API returns.
// return error;
});
// console.log(event_file_obj_post_promise);
if (return_obj) {
return event_file_obj_post_promise;
} else {
return event_file_obj_post_promise.event_file_id_random;
}
}
// Updated 2024-06-13
export async function update_ae_obj__event_file(
{
api_cfg,
event_file_id,
data_kv,
params = {},
log_lvl = 1
}: {
api_cfg: any,
event_file_id: string,
data_kv: key_val,
params?: key_val,
log_lvl?: number
}
) {
if (log_lvl) {
console.log(`*** update_ae_obj__event_file() *** event_file_id=${event_file_id}`);
}
ae_promises.update__event_file_obj = await api.update_ae_obj_id_crud({
api_cfg: api_cfg,
obj_type: 'event_file',
obj_id: event_file_id, // NOTE: This is the FQDN, not normally the ID.
fields: data_kv,
key: api_cfg.api_crud_super_key,
params: params,
return_obj: true,
log_lvl: log_lvl
})
.then(function (event_file_obj_update_result) {
if (event_file_obj_update_result) {
// db_save_ae_obj_li__event_file({obj_type: 'event_file', obj_li: [event_file_obj_update_result]});
// Very important: The results returned from the API does not include fields from the DB views. It is the actual table fields only.
db_update_ae_obj_id__event_file({obj_type: 'event_file', obj_id: event_file_id, data_kv: event_file_obj_update_result});
return event_file_obj_update_result;
} else {
return null;
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
})
.finally(function () {
});
if (log_lvl) {
console.log('ae_promises.update__event_file_obj:', ae_promises.update__event_file_obj);
}
return ae_promises.update__event_file_obj;
}
// Updated 2024-07-12
export async function search__event_file(
{
api_cfg,
event_id,
created_on = null,
fulltext_search_qry_str,
ft_file_search_qry_str,
like_search_qry_str = null,
like_presentation_search_qry_str = null,
like_file_search_qry_str = null,
order_by_li = {'priority': 'DESC', 'sort': 'DESC', 'created_on': 'DESC', 'updated_on': 'DESC', 'filename': 'ASC', 'extension': 'ASC', 'hosted_file_size': 'ASC'},
params = {},
try_cache = true,
log_lvl = 0
}: {
api_cfg: any,
event_id: any,
created_on?: null|string,
fulltext_search_qry_str?: null|string,
ft_file_search_qry_str?: null|string,
like_search_qry_str?: null|string,
like_presentation_search_qry_str?: null|string,
like_file_search_qry_str?: null|string,
order_by_li?: key_val,
params?: any,
try_cache?: boolean,
log_lvl?: number
}
) {
if (log_lvl) {
console.log(`*** search__event_file() *** event_id=${event_id}`);
}
let enabled: string = (params.qry__enabled ?? 'enabled'); // all, disabled, enabled
let hidden: string = (params.qry__hidden ?? 'not_hidden'); // all, hidden, not_hidden
let limit: number = (params.qry__limit ?? 25); // 99
let offset: number = (params.qry__offset ?? 0); // 0
let params_json: key_val = {};
// if (!fulltext_search_qry_str && !like_search_qry_str) {
// console.log('No search string provided!!!');
// return false; // Returning false instead of [] because no search was performed.
// }
if (fulltext_search_qry_str || ft_file_search_qry_str) {
params_json['ft_qry'] = {};
if (fulltext_search_qry_str && fulltext_search_qry_str.length > 2) {
params_json['ft_qry']['default_qry_str'] = fulltext_search_qry_str;
}
if (ft_file_search_qry_str && ft_file_search_qry_str.length > 2) {
params_json['ft_qry']['event_file_li_qry_str'] = ft_file_search_qry_str;
}
}
// Use the AND (AND LIKE) query
// if (like_search_qry_str || like_file_search_qry_str) {
// params_json['and_like'] = {};
// if (like_search_qry_str && like_search_qry_str.length > 2) {
// params_json['and_like']['default_qry_str'] = like_search_qry_str;
// }
// if (like_file_search_qry_str && like_file_search_qry_str.length > 2) {
// params_json['and_like']['event_file_li_qry_str'] = like_file_search_qry_str;
// }
// }
// Use the AND (OR LIKE) query
// if (like_search_qry_str || like_presentation_search_qry_str || like_file_search_qry_str) {
// params_json['or_like'] = {};
// if (like_search_qry_str && like_search_qry_str.length > 2) {
// params_json['or_like']['default_qry_str'] = like_search_qry_str;
// }
// if (like_presentation_search_qry_str && like_presentation_search_qry_str.length > 2) {
// params_json['or_like']['event_presentation_li_qry_str'] = like_presentation_search_qry_str;
// }
// if (like_file_search_qry_str && like_file_search_qry_str.length > 2) {
// params_json['or_like']['event_file_li_qry_str'] = like_file_search_qry_str;
// }
// }
// params_json['and_qry'] = {};
// if (created_on) {
// params_json['and_qry']['created_on'] = created_on;
// }
ae_promises.load__event_file_obj_li = await api.get_ae_obj_li_for_obj_id_crud({
api_cfg: api_cfg,
obj_type: 'event_file',
for_obj_type: 'event',
for_obj_id: event_id,
use_alt_table: true, // NOTE: We want to use the alt table for file searching?
use_alt_base: false,
enabled: enabled,
hidden: hidden,
order_by_li: order_by_li,
limit: limit,
offset: offset,
params_json: params_json,
params: params,
log_lvl: log_lvl
})
.then(function (event_file_obj_li_get_result) {
if (event_file_obj_li_get_result) {
db_save_ae_obj_li__event_file({obj_type: 'event_file', obj_li: event_file_obj_li_get_result});
return event_file_obj_li_get_result;
} else {
return [];
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
})
.finally(function () {
});
if (log_lvl) {
console.log('ae_promises.load__event_file_obj_li:', ae_promises.load__event_file_obj_li);
}
return ae_promises.load__event_file_obj_li;
}
// This function will loop through the event_file_obj_li and save each one to the DB.
// Updated 2024-10-04
export function db_save_ae_obj_li__event_file(
{
obj_type,
obj_li,
log_lvl = 0
}: {
obj_type: string,
obj_li: any,
log_lvl?: number
}
) {
if (log_lvl) {
console.log(`*** db_save_ae_obj_li__event_file() ***`);
}
if (obj_li && obj_li.length) {
obj_li.forEach(async function (obj: any) {
if (log_lvl) {
console.log(`ae_obj ${obj_type}:`, obj);
}
try {
const id_random = await db_events.files.put({
id: obj.event_file_id_random,
id_random: obj.event_file_id_random,
event_file_id: obj.event_file_id_random,
event_file_id_random: obj.event_file_id_random,
hosted_file_id: obj.hosted_file_id_random,
hosted_file_id_random: obj.hosted_file_id_random,
hash_sha256: obj.hash_sha256, // Renamed with alias in FastAPI model
for_type: obj.for_type,
for_id: obj.for_id_id_random,
for_id_random: obj.for_id_random,
event_id_random: obj.event_id_random,
event_session_id_random: obj.event_session_id_random,
event_presentation_id_random: obj.event_presentation_id_random,
event_presenter_id_random: obj.event_presenter_id_random,
event_location_id_random: obj.event_location_id_random,
filename: obj.filename,
extension: obj.extension,
open_in_os: obj.open_in_os,
lu_file_purpose_id: obj.lu_file_purpose_id, // Not id_random in this case?
lu_event_file_purpose_name: obj.lu_event_file_purpose_name,
file_purpose: obj.file_purpose,
enable: obj.enable,
hide: obj.hide,
priority: obj.priority,
sort: obj.sort,
group: obj.group,
notes: obj.notes,
created_on: obj.created_on,
updated_on: obj.updated_on,
filename_no_ext: obj.filename_no_ext,
filename_w_ext: obj.filename_w_ext,
hosted_file_content_type: obj.hosted_file_content_type,
file_size: obj.file_size,
hosted_file_size: obj.hosted_file_size,
event_location_code: obj.event_location_code,
event_location_name: obj.event_location_name,
event_session_code: obj.event_session_code,
event_session_type_code: obj.event_session_type_code,
event_session_name: obj.event_session_name,
event_session_start_datetime: obj.event_session_start_datetime,
event_session_end_datetime: obj.event_session_end_datetime,
event_presentation_code: obj.event_presentation_code,
event_presentation_type_code: obj.event_presentation_type_code,
event_presentation_name: obj.event_presentation_name,
event_presentation_start_datetime: obj.event_presentation_start_datetime,
event_presentation_end_datetime: obj.event_presentation_end_datetime,
event_presenter_given_name: obj.event_presenter_given_name,
event_presenter_family_name: obj.event_presenter_family_name,
event_presenter_full_name: obj.event_presenter_full_name,
event_presenter_email: obj.event_presenter_email,
});
// console.log(`Put obj with ID: ${obj.event_file_id_random} or ${id_random}`);
} catch (error) {
let status = `Failed to put ${obj.event_file_id_random}: ${error}`;
console.log(status);
}
// const id_random = await db_events.files.put(obj);
// console.log(`Put obj with ID: ${obj.event_file_id_random}`);
});
return true;
}
return false;
}
export function db_update_ae_obj_id__event_file(
{
obj_type,
obj_id,
data_kv,
}: {
obj_type: string,
obj_id: string,
data_kv: key_val
}
) {
console.log(`*** db_update_ae_obj_id__event_file() ***`);
if (obj_id) {
console.log(`ae_obj ${obj_type}:`, obj_id);
try {
// db_events.files.update(obj_id, data_kv);
db_events.files.update(obj_id,
{
// for_type: data_kv.for_type,
// for_id: data_kv.for_id_id_random,
// for_id_random: data_kv.for_id_random,
// event_id_random: data_kv.event_id_random,
// event_session_id_random: data_kv.event_session_id_random,
// event_presentation_id_random: data_kv.event_presentation_id_random,
// event_presenter_id_random: data_kv.event_presenter_id_random,
// event_location_id_random: data_kv.event_location_id_random,
filename: data_kv.filename,
extension: data_kv.extension,
open_in_os: data_kv.open_in_os,
// lu_file_purpose_id: data_kv.lu_file_purpose_id, // Not id_random in this case?
// lu_event_file_purpose_name: data_kv.lu_event_file_purpose_name,
file_purpose: data_kv.file_purpose,
// enable: data_kv.enable,
// hide: data_kv.hide,
// priority: data_kv.priority,
// sort: data_kv.sort,
// group: data_kv.group,
// notes: data_kv.notes,
// created_on: data_kv.created_on,
// updated_on: data_kv.updated_on,
filename_no_ext: data_kv.filename_no_ext,
filename_w_ext: data_kv.filename_w_ext,
// hosted_file_content_type: data_kv.hosted_file_content_type,
// file_size: data_kv.file_size,
// hosted_file_size: data_kv.hosted_file_size,
// event_location_code: data_kv.event_location_code,
// event_location_name: data_kv.event_location_name,
// event_session_code: data_kv.event_session_code,
// event_session_name: data_kv.event_session_name,
// event_session_start_datetime: data_kv.event_session_start_datetime,
// event_presentation_code: data_kv.event_presentation_code,
// event_presentation_name: data_kv.event_presentation_name,
// event_presentation_start_datetime: data_kv.event_presentation_start_datetime,
// event_presenter_given_name: data_kv.event_presenter_given_name,
// event_presenter_family_name: data_kv.event_presenter_family_name,
// event_presenter_full_name: data_kv.event_presenter_full_name,
// event_presenter_email: data_kv.event_presenter_email,
}
);
console.log(`Update obj with ID: ${obj_id}`);
} catch (error) {
let status = `Failed to update ${obj_id}: ${error}`;
console.log(status);
}
// const id_random = await db_events.files.put(obj);
// console.log(`Put obj with ID: ${data_kv.event_file_id_random}`);
return true;
}
return false;
}

View File

@@ -0,0 +1,584 @@
import type { key_val } from '$lib/ae_stores';
import { api } from '$lib/api';
import { db_events } from "$lib/db_events";
import { load_ae_obj_li__event_file } from "$lib/ae_events__event_file";
import { load_ae_obj_li__event_session } from './ae_events__event_session';
let ae_promises: key_val = {};
// Updated 2024-06-10
export async function load_ae_obj_id__event_location(
{
api_cfg,
event_location_id,
inc_file_li = false,
inc_session_li = false,
try_cache = true,
log_lvl = 0
}: {
api_cfg: any,
event_location_id: string,
inc_file_li?: boolean,
inc_session_li?: boolean,
try_cache?: boolean,
log_lvl?: number
}
) {
console.log(`*** load_ae_obj_id__event_location() *** event_location_id=${event_location_id}`);
let params = {};
// $events_sess.badges.status_load__event_location_obj = 'loading';
ae_promises.load__event_location_obj = await api.get_ae_obj_id_crud({
api_cfg: api_cfg,
obj_type: 'event_location',
obj_id: event_location_id, // NOTE: This is the FQDN, not normally the ID.
use_alt_table: true, // NOTE: This will use the table_name_alt value instead of the table_name value in the API config.
use_alt_base: false, // NOTE: This will use the base_name_alt value instead of the base_name value in the API config.
params: params,
log_lvl: log_lvl
})
.then(function (event_location_obj_get_result) {
if (event_location_obj_get_result) {
if (try_cache) {
// This is expecting a list
db_save_ae_obj_li__event_location({
obj_type: 'event_location',
obj_li: [event_location_obj_get_result]
});
}
return event_location_obj_get_result;
} else {
console.log('No results returned.');
return null;
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
});
if (log_lvl) {
console.log('ae_promises.load__event_location_obj:', ae_promises.load__event_location_obj);
}
if (inc_file_li) {
// Load the files for the location
if (log_lvl) {
console.log(`Need to load the file list for the location now`);
}
let load_event_file_obj_li = load_ae_obj_li__event_file({
api_cfg: api_cfg,
for_obj_type: 'event_location',
for_obj_id: event_location_id,
params: {qry__enabled: 'all', qry__limit: 15},
try_cache: try_cache,
log_lvl: log_lvl
})
.then((event_file_obj_li) => {
if (log_lvl) {
console.log(`event_file_obj_li = `, event_file_obj_li);
}
return event_file_obj_li;
});
if (log_lvl) {
console.log(`load_event_file_obj_li = `, load_event_file_obj_li);
}
ae_promises.load__event_location_obj.event_file_li = load_event_file_obj_li;
}
if (inc_session_li) {
// Load the sessions for the location
if (log_lvl) {
console.log(`Need to load the session list for the location now`);
}
let load_event_session_obj_li = load_ae_obj_li__event_session({
api_cfg: api_cfg,
for_obj_type: 'event_location',
for_obj_id: event_location_id,
params: {qry__enabled: 'all', qry__limit: 15},
try_cache: try_cache,
log_lvl: log_lvl
})
.then((event_session_obj_li) => {
if (log_lvl) {
console.log(`event_session_obj_li = `, event_session_obj_li);
}
// if (try_cache) {
// console.log(`ae_promises.load__event_session_obj = `, ae_promises.load__event_session_obj);
// ae_promises.load__event_session_obj.event_session_li = event_session_obj_li;
// // Re-save the session object with the new session list
// db_save_ae_obj_li__event_session({
// obj_type: 'event_session',
// obj_li: [ae_promises.load__event_session_obj]
// });
// }
return event_session_obj_li;
});
if (log_lvl) {
console.log(`load_event_session_obj_li = `, load_event_session_obj_li);
}
ae_promises.load__event_location_obj.event_session_li = load_event_session_obj_li;
}
return ae_promises.load__event_location_obj;
}
// Updated 2024-09-24
export async function load_ae_obj_li__event_location(
{
api_cfg,
for_obj_type,
for_obj_id,
inc_file_li = false,
inc_session_li = false,
order_by_li = {'priority': 'DESC', 'sort': 'DESC', 'name': 'ASC', 'code': 'ASC', 'updated_on': 'DESC', 'created_on': 'DESC'},
params = {},
try_cache = true,
log_lvl = 0
}: {
api_cfg: any,
for_obj_type: string,
for_obj_id: string,
inc_file_li?: boolean,
inc_session_li?: boolean,
order_by_li?: key_val,
params?: key_val,
try_cache?: boolean,
log_lvl?: number
}
) {
console.log(`*** load_ae_obj_li__event_location() *** for_obj_type=${for_obj_type} for_obj_id=${for_obj_id}`);
let enabled: string = (params.qry__enabled ?? 'enabled'); // all, disabled, enabled
let hidden: string = (params.qry__hidden ?? 'all'); // all, hidden, not_hidden
let limit: number = (params.qry__limit ?? 99); // 99
let offset: number = (params.qry__offset ?? 0); // 0
let params_json: key_val = {};
// console.log('params_json:', params_json);
ae_promises.load__event_location_obj_li = await api.get_ae_obj_li_for_obj_id_crud({
api_cfg: api_cfg,
obj_type: 'event_location',
for_obj_type: for_obj_type,
for_obj_id: for_obj_id,
use_alt_table: true, // NOTE: This will use the table_name_alt value instead of the table_name value in the API config.
use_alt_base: false, // NOTE: This will use the base_name_alt value instead of the base_name value
enabled: enabled,
hidden: hidden,
order_by_li: order_by_li,
limit: limit,
offset: offset,
params_json: params_json,
params: params,
log_lvl: log_lvl
})
.then(function (event_location_obj_li_get_result) {
if (event_location_obj_li_get_result) {
if (try_cache) {
db_save_ae_obj_li__event_location({
obj_type: 'event_location',
obj_li: event_location_obj_li_get_result
});
}
return event_location_obj_li_get_result;
} else {
return [];
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
});
if (log_lvl) {
console.log('ae_promises.load__event_location_obj_li:', ae_promises.load__event_location_obj_li);
}
if (inc_file_li) {
// Load the files for the locations
if (log_lvl) {
console.log(`Need to load the file list for each location now`);
}
for (let i = 0; i < ae_promises.load__event_location_obj_li.length; i++) {
let event_location_obj = ae_promises.load__event_location_obj_li[i];
let event_location_id = event_location_obj.event_location_id_random;
let load_event_file_obj_li = load_ae_obj_li__event_file({
api_cfg: api_cfg,
for_obj_type: 'event_location',
for_obj_id: event_location_id,
params: {qry__enabled: enabled, qry__limit: limit},
try_cache: try_cache,
log_lvl: log_lvl
})
.then((event_file_obj_li) => {
if (log_lvl) {
console.log(`event_file_obj_li = `, event_file_obj_li);
}
return event_file_obj_li;
});
if (log_lvl) {
console.log(`load_event_file_obj_li = `, load_event_file_obj_li);
}
}
}
if (inc_session_li) {
// Load the sessions for the locations
if (log_lvl) {
console.log(`Need to load the session list for each location now`);
}
for (let i = 0; i < ae_promises.load__event_location_obj_li.length; i++) {
let event_location_obj = ae_promises.load__event_location_obj_li[i];
let event_location_id = event_location_obj.event_location_id_random;
let load_event_session_obj_li = load_ae_obj_li__event_session({
api_cfg: api_cfg,
for_obj_type: 'event_location',
for_obj_id: event_location_id,
params: {qry__enabled: enabled, qry__limit: limit},
try_cache: try_cache,
log_lvl: log_lvl
})
.then((event_session_obj_li) => {
if (log_lvl) {
console.log(`event_session_obj_li = `, event_session_obj_li);
}
return event_session_obj_li;
});
if (log_lvl) {
console.log(`load_event_session_obj_li = `, load_event_session_obj_li);
}
}
}
return ae_promises.load__event_location_obj_li;
}
// Updated 2024-06-25
export async function create_ae_obj__event_location(
{
api_cfg,
event_id,
data_kv,
params={},
log_lvl=0
}: {
api_cfg: any,
event_id: string,
data_kv: key_val,
params?: key_val,
log_lvl?: number
}
) {
console.log(`*** create_ae_obj__event_location() *** event_id=${event_id}`);
ae_promises.create__event_location = await api.create_ae_obj_crud({
api_cfg: api_cfg,
obj_type: 'event_location',
fields: {
event_id_random: event_id,
...data_kv
},
key: api_cfg.api_crud_super_key,
params: params,
return_obj: true,
log_lvl: log_lvl
})
.then(function (event_location_obj_create_result) {
if (event_location_obj_create_result) {
db_save_ae_obj_li__event_location(
{
obj_type: 'event_location',
obj_li: [event_location_obj_create_result]
});
return event_location_obj_create_result;
} else {
return null;
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
})
.finally(function () {
});
if (log_lvl) {
console.log('ae_promises.create__event_location:', ae_promises.create__event_location);
}
return ae_promises.create__event_location;
}
// Updated 2024-09-25
export async function update_ae_obj__event_location(
{
api_cfg,
event_location_id,
data_kv,
params = {},
try_cache = true,
log_lvl = 0
}: {
api_cfg: any,
event_location_id: string,
data_kv: key_val,
params?: key_val,
try_cache?: boolean,
log_lvl?: number
}
) {
if (log_lvl) {
console.log(`*** update_ae_obj__event_location() *** event_location_id=${event_location_id}`, data_kv);
}
ae_promises.update__event_location_obj = await api.update_ae_obj_id_crud({
api_cfg: api_cfg,
obj_type: 'event_location',
obj_id: event_location_id,
fields: data_kv,
key: api_cfg.api_crud_super_key,
params: params,
return_obj: true,
log_lvl: log_lvl
})
.then(function (event_location_obj_update_result) {
if (event_location_obj_update_result) {
if (try_cache) {
db_save_ae_obj_li__event_location({
obj_type: 'event_location', obj_li: [event_location_obj_update_result]
});
}
return event_location_obj_update_result;
} else {
return null;
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
})
.finally(function () {
});
if (log_lvl) {
console.log('ae_promises.update__event_location_obj:', ae_promises.update__event_location_obj);
}
return ae_promises.update__event_location_obj;
}
export async function search__event_location(
{
api_cfg,
event_id,
fulltext_search_qry_str,
ft_presenter_search_qry_str,
like_search_qry_str = null,
like_presentation_search_qry_str = null,
like_presenter_search_qry_str = null,
params = {},
try_cache = true,
log_lvl = 0
}: {
api_cfg: any,
event_id: any,
fulltext_search_qry_str?: null|string,
ft_presenter_search_qry_str?: null|string,
like_search_qry_str?: null|string,
like_presentation_search_qry_str?: null|string,
like_presenter_search_qry_str?: null|string,
params?: any,
try_cache?: boolean,
log_lvl?: number
}
) {
console.log(`*** search__event_location() *** event_id=${event_id}`);
let enabled: string = (params.qry__enabled ?? 'enabled'); // all, disabled, enabled
let hidden: string = (params.qry__hidden ?? 'not_hidden'); // all, hidden, not_hidden
let limit: number = (params.qry__limit ?? 25); // 99
let offset: number = (params.qry__offset ?? 0); // 0
let params_json: key_val = {};
if (!fulltext_search_qry_str && !like_search_qry_str) {
console.log('No search string provided!!!');
return false; // Returning false instead of [] because no search was performed.
}
if (fulltext_search_qry_str || ft_presenter_search_qry_str) {
params_json['ft_qry'] = {};
if (fulltext_search_qry_str && fulltext_search_qry_str.length > 2) {
params_json['ft_qry']['default_qry_str'] = fulltext_search_qry_str;
}
if (ft_presenter_search_qry_str && ft_presenter_search_qry_str.length > 2) {
params_json['ft_qry']['event_presenter_li_qry_str'] = ft_presenter_search_qry_str;
}
}
// Use the AND (AND LIKE) query
// if (like_search_qry_str || like_presenter_search_qry_str) {
// params_json['and_like'] = {};
// if (like_search_qry_str && like_search_qry_str.length > 2) {
// params_json['and_like']['default_qry_str'] = like_search_qry_str;
// }
// if (like_presenter_search_qry_str && like_presenter_search_qry_str.length > 2) {
// params_json['and_like']['event_presenter_li_qry_str'] = like_presenter_search_qry_str;
// }
// }
// Use the AND (OR LIKE) query
if (like_search_qry_str || like_presentation_search_qry_str || like_presenter_search_qry_str) {
params_json['or_like'] = {};
if (like_search_qry_str && like_search_qry_str.length > 2) {
params_json['or_like']['default_qry_str'] = like_search_qry_str;
}
if (like_presentation_search_qry_str && like_presentation_search_qry_str.length > 2) {
params_json['or_like']['event_presentation_li_qry_str'] = like_presentation_search_qry_str;
}
if (like_presenter_search_qry_str && like_presenter_search_qry_str.length > 2) {
params_json['or_like']['event_presenter_li_qry_str'] = like_presenter_search_qry_str;
}
}
params_json['and_qry'] = {};
// if (location_type_code) {
// params_json['and_qry']['location_type_code'] = location_type_code;
// }
let order_by_li = {'priority': 'DESC', 'sort': 'DESC', 'start_datetime': 'ASC', 'name': 'ASC', 'updated_on': 'DESC', 'created_on': 'DESC'};
ae_promises.load__event_location_obj_li = await api.get_ae_obj_li_for_obj_id_crud({
api_cfg: api_cfg,
obj_type: 'event_location',
for_obj_type: 'event',
for_obj_id: event_id,
use_alt_table: true, // NOTE: We want to use the alt table for location searching
use_alt_base: false,
enabled: enabled,
hidden: hidden,
order_by_li: order_by_li,
limit: limit,
offset: offset,
params_json: params_json,
params: params,
log_lvl: log_lvl
})
.then(function (event_location_obj_li_get_result) {
if (event_location_obj_li_get_result) {
db_save_ae_obj_li__event_location({obj_type: 'event_location', obj_li: event_location_obj_li_get_result});
return event_location_obj_li_get_result;
} else {
return [];
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
})
.finally(function () {
});
if (log_lvl) {
console.log('ae_promises.load__event_location_obj_li:', ae_promises.load__event_location_obj_li);
}
return ae_promises.load__event_location_obj_li;
}
// This function will loop through the event_location_obj_li and save each one to the DB.
// Updated 2024-06-25
export function db_save_ae_obj_li__event_location(
{
obj_type,
obj_li,
log_lvl = 0
}: {
obj_type: string,
obj_li: any,
log_lvl?: number
}
) {
if (log_lvl) {
console.log(`*** db_save_ae_obj_li__event_location() ***`);
}
if (obj_li && obj_li.length) {
obj_li.forEach(async function (obj: any) {
if (log_lvl) {
console.log(`ae_obj ${obj_type}:`, obj);
}
try {
const id_random = await db_events.locations.put({
id: obj.event_location_id_random,
event_location_id: obj.event_location_id_random,
event_location_id_random: obj.event_location_id_random,
external_id: obj.external_id,
code: obj.code,
type_code: obj.type_code,
event_id: obj.event_id_random,
event_id_random: obj.event_id_random,
name: obj.name,
description: obj.description,
passcode: obj.passcode,
hide_event_launcher: obj.hide_event_launcher,
alert: obj.alert,
alert_msg: obj.alert_msg,
data_json: obj.data_json,
enable: obj.enable,
hide: obj.hide,
priority: obj.priority,
sort: obj.sort,
group: obj.group,
notes: obj.notes,
created_on: obj.created_on,
updated_on: obj.updated_on,
// From SQL view
file_count: obj.file_count,
file_count_all: obj.file_count_all,
internal_use_count: obj.internal_use_count,
event_file_id_li_json: obj.event_file_id_li_json,
// poc_person_given_name: obj.poc_person_given_name,
// poc_person_family_name: obj.poc_person_family_name,
// poc_person_full_name: obj.poc_person_full_name,
// poc_person_primary_email: obj.poc_person_primary_email,
// poc_person_passcode: obj.poc_person_passcode,
// poc_kv_json: obj.poc_kv_json,
event_name: obj.event_name,
});
// console.log(`Put obj with ID: ${obj.event_location_id_random} or ${id_random}`);
} catch (error) {
let status = `Failed to put ${obj.event_location_id_random}: ${error}`;
console.log(status);
}
// const id_random = await db_events.locations.put(obj);
// console.log(`Put obj with ID: ${obj.event_location_id_random}`);
});
return true;
}
}

View File

@@ -0,0 +1,456 @@
import type { key_val } from '$lib/ae_stores';
import { api } from '$lib/api';
import { db_events } from "$lib/db_events";
import { load_ae_obj_li__event_file } from "$lib/ae_events__event_file";
import { load_ae_obj_li__event_presenter } from "$lib/ae_events__event_presenter";
let ae_promises: key_val = {};
// Updated 2024-10-08
export async function load_ae_obj_id__event_presentation(
{
api_cfg,
event_presentation_id,
inc_file_li = false,
inc_presenter_li = false,
try_cache = true,
log_lvl = 0
}: {
api_cfg: any,
event_presentation_id: string,
inc_file_li?: boolean,
inc_presenter_li?: boolean,
try_cache?: boolean,
log_lvl?: number
}
) {
console.log(`*** load_ae_obj_id__event_presentation() *** event_presentation_id=${event_presentation_id}`);
let params = {};
ae_promises.load__event_presentation_obj = await api.get_ae_obj_id_crud({
api_cfg: api_cfg,
obj_type: 'event_presentation',
obj_id: event_presentation_id, // NOTE: This is the FQDN, not normally the ID.
use_alt_table: false, // NOTE: This will use the table_name_alt value instead of the table_name value in the API config.
use_alt_base: false, // NOTE: This will use the base_name_alt value instead of the base_name value
params: params,
log_lvl: log_lvl
})
.then(function (event_presentation_obj_get_result) {
if (event_presentation_obj_get_result) {
if (try_cache) {
// This is expecting a list
db_save_ae_obj_li__event_presentation({
obj_type: 'event_presentation',
obj_li: [event_presentation_obj_get_result]
});
}
return event_presentation_obj_get_result;
} else {
console.log('No results returned.');
return null;
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
});
if (inc_file_li) {
// Load the files for the presentation
if (log_lvl) {
console.log(`Need to load the file list for the presentation now.`);
}
let load_event_file_obj_li = load_ae_obj_li__event_file({
api_cfg: api_cfg,
for_obj_type: 'event_presentation',
for_obj_id: event_presentation_id,
params: {qry__enabled: 'all', qry__limit: 25},
try_cache: try_cache,
log_lvl: log_lvl
})
.then((event_file_obj_li) => {
if (log_lvl) {
console.log(`event_file_obj_li = `, event_file_obj_li);
}
return event_file_obj_li;
});
if (log_lvl) {
console.log(`event_file_obj_li = `, load_event_file_obj_li);
}
ae_promises.load__event_presentation_obj.event_file_li = load_event_file_obj_li;
}
if (inc_presenter_li) {
// Load the presenters for the presentation
if (log_lvl) {
console.log(`Need to load the presenter list for the presentation now.`);
}
let load_event_presenter_obj_li = load_ae_obj_li__event_presenter({
api_cfg: api_cfg,
for_obj_type: 'event_presentation',
for_obj_id: event_presentation_id,
inc_file_li: inc_file_li,
params: {qry__enabled: 'all', qry__limit: 25},
try_cache: try_cache,
log_lvl: log_lvl
})
.then((event_presenter_obj_li) => {
if (log_lvl) {
console.log(`event_presenter_obj_li = `, event_presenter_obj_li);
}
return event_presenter_obj_li;
});
if (log_lvl) {
console.log(`event_presenter_obj_li = `, load_event_presenter_obj_li);
}
ae_promises.load__event_presentation_obj.event_presenter_li = load_event_presenter_obj_li;
}
return ae_promises.load__event_presentation_obj;
}
// Updated 2024-10-08
export async function load_ae_obj_li__event_presentation(
{
api_cfg,
for_obj_type = 'event_session',
for_obj_id,
inc_file_li = false,
inc_presenter_li = false,
order_by_li = {'priority': 'DESC', 'sort': 'DESC', 'start_datetime': 'ASC', 'name': 'ASC', 'updated_on': 'DESC', 'created_on': 'DESC'},
params = {},
try_cache = true,
log_lvl = 0
}: {
api_cfg: any,
for_obj_type: string,
for_obj_id: string,
inc_file_li?: boolean,
inc_presenter_li?: boolean,
order_by_li?: key_val,
params?: key_val,
try_cache?: boolean,
log_lvl?: number
}
) {
console.log(`*** load_ae_obj_li__event_presentation() *** for_obj_type=${for_obj_type} for_obj_id=${for_obj_id}`);
let enabled: string = (params.qry__enabled ?? 'enabled'); // all, disabled, enabled
let hidden: string = (params.qry__hidden ?? 'not_hidden'); // all, hidden, not_hidden
let limit: number = (params.qry__limit ?? 99); // 99
let offset: number = (params.qry__offset ?? 0); // 0
let params_json: key_val = {};
// console('params_json:', params_json);
ae_promises.load__event_presentation_obj_li = await api.get_ae_obj_li_for_obj_id_crud({
api_cfg: api_cfg,
obj_type: 'event_presentation',
for_obj_type: for_obj_type,
for_obj_id: for_obj_id,
use_alt_table: true, // NOTE: This will use the table_name_alt value instead of the table_name value in the API config.
use_alt_base: false, // NOTE: This will use the base_name_alt value instead of the base_name value
enabled: enabled,
hidden: hidden,
order_by_li: order_by_li,
limit: limit,
offset: offset,
params_json: params_json,
params: params,
log_lvl: log_lvl
})
.then(function (event_presentation_obj_li_get_result) {
if (event_presentation_obj_li_get_result) {
if (try_cache) {
db_save_ae_obj_li__event_presentation({
obj_type: 'event_presentation', obj_li: event_presentation_obj_li_get_result
});
}
return event_presentation_obj_li_get_result;
} else {
return [];
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
});
if (log_lvl) {
console.log('ae_promises.load__event_presentation_obj_li:', ae_promises.load__event_presentation_obj_li);
}
if (inc_file_li) {
// Load the files for the presentations
if (log_lvl) {
console.log(`Need to load the file list for each presentation now.`);
}
for (let i = 0; i < ae_promises.load__event_presentation_obj_li.length; i++) {
let event_presentation_obj = ae_promises.load__event_presentation_obj_li[i];
let event_presentation_id = event_presentation_obj.event_presentation_id_random;
let load_event_file_obj_li = load_ae_obj_li__event_file({
api_cfg: api_cfg,
for_obj_type: 'event_presentation',
for_obj_id: event_presentation_id,
params: {qry__enabled: 'all', qry__limit: 25},
try_cache: try_cache,
log_lvl: log_lvl
})
.then((event_file_obj_li) => {
if (log_lvl) {
console.log(`event_file_obj_li = `, event_file_obj_li);
}
return event_file_obj_li;
});
if (log_lvl) {
console.log(`event_file_obj_li = `, load_event_file_obj_li);
}
// ae_promises.load__event_presentation_obj.event_file_li = load_event_file_obj_li;
}
}
if (inc_presenter_li) {
// Load the presenters for the presentations
if (log_lvl) {
console.log(`Need to load the presenter list for each presentation now.`);
}
for (let i = 0; i < ae_promises.load__event_presentation_obj_li.length; i++) {
let event_presentation_obj = ae_promises.load__event_presentation_obj_li[i];
let event_presentation_id = event_presentation_obj.event_presentation_id_random;
let load_event_presenter_obj_li = load_ae_obj_li__event_presenter({
api_cfg: api_cfg,
for_obj_type: 'event_presentation',
for_obj_id: event_presentation_id,
params: {qry__enabled: 'all', qry__limit: 25},
try_cache: try_cache,
log_lvl: log_lvl
})
.then((event_presenter_obj_li) => {
if (log_lvl) {
console.log(`event_presenter_obj_li = `, event_presenter_obj_li);
}
return event_presenter_obj_li;
});
if (log_lvl) {
console.log(`event_presenter_obj_li = `, load_event_presenter_obj_li);
}
// ae_promises.load__event_presentation_obj.event_presenter_li = load_event_presenter_obj_li;
}
}
return ae_promises.load__event_presentation_obj_li;
}
// Updated 2024-06-24
export async function create_ae_obj__event_presentation(
{
api_cfg,
event_id,
event_session_id,
data_kv,
params = {},
log_lvl = 0
}: {
api_cfg: any,
event_id: string,
event_session_id: string,
data_kv: key_val,
params?: key_val,
log_lvl?: number
}
) {
console.log(`*** create_ae_obj__event_presentation() *** event_id=${event_id} event_session_id=${event_session_id}`);
ae_promises.create__event_presentation = await api.create_ae_obj_crud({
api_cfg: api_cfg,
obj_type: 'event_presentation',
fields: {
event_id_random: event_id,
event_session_id_random: event_session_id,
...data_kv
},
key: api_cfg.api_crud_super_key,
params: params,
return_obj: true,
log_lvl: log_lvl
})
.then(function (event_presentation_obj_create_result) {
if (event_presentation_obj_create_result) {
db_save_ae_obj_li__event_presentation(
{
obj_type: 'event_presentation',
obj_li: [event_presentation_obj_create_result]
});
return event_presentation_obj_create_result;
} else {
return null;
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
})
.finally(function () {
});
if (log_lvl) {
console.log('ae_promises.create__event_presentation:', ae_promises.create__event_presentation);
}
return ae_promises.create__event_presentation;
}
// Updated 2024-09-25
export async function update_ae_obj__event_presentation(
{
api_cfg,
event_presentation_id,
data_kv,
params = {},
try_cache = true,
log_lvl = 0
}: {
api_cfg: any,
event_presentation_id: string,
data_kv: key_val,
params?: key_val,
try_cache?: boolean,
log_lvl?: number
}
) {
if (log_lvl) {
console.log(`*** update_ae_obj__event_presentation() *** event_presentation_id=${event_presentation_id}`, data_kv);
}
ae_promises.update__event_presentation_obj = await api.update_ae_obj_id_crud({
api_cfg: api_cfg,
obj_type: 'event_presentation',
obj_id: event_presentation_id,
fields: data_kv,
key: api_cfg.api_crud_super_key,
params: params,
return_obj: true,
log_lvl: log_lvl
})
.then(function (event_presentation_obj_update_result) {
if (event_presentation_obj_update_result) {
if (try_cache) {
db_save_ae_obj_li__event_presentation({
obj_type: 'event_presentation', obj_li: [event_presentation_obj_update_result]
});
}
return event_presentation_obj_update_result;
} else {
return null;
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
})
.finally(function () {
});
if (log_lvl) {
console.log('ae_promises.update__event_presentation_obj:', ae_promises.update__event_presentation_obj);
}
return ae_promises.update__event_presentation_obj;
}
// This function will loop through the event_presentation_obj_li and save each one to the DB.
// Updated 2024-06-10
export function db_save_ae_obj_li__event_presentation(
{
obj_type,
obj_li,
log_lvl = 0
}: {
obj_type: string,
obj_li: any,
log_lvl?: number
}
) {
if (log_lvl) {
console.log(`*** db_save_ae_obj_li__event_presentation() ***`);
}
if (obj_li && obj_li.length) {
obj_li.forEach(async function (obj: any) {
if (log_lvl) {
console.log(`ae_obj ${obj_type}:`, obj);
}
try {
const id_random = await db_events.presentations.put({
id: obj.event_presentation_id_random,
// id_random: obj.event_presentation_id_random,
event_presentation_id: obj.event_presentation_id_random,
event_presentation_id_random: obj.event_presentation_id_random,
external_id: obj.external_id,
code: obj.code,
for_type: obj.for_type,
for_id: obj.for_id_random,
for_id_random: obj.for_id_random,
type_code: obj.type_code,
event_id: obj.event_id_random,
event_id_random: obj.event_id_random,
event_session_id: obj.event_session_id_random,
event_session_id_random: obj.event_session_id_random,
event_abstract_id: obj.event_abstract_id_random,
event_abstract_id_random: obj.event_abstract_id_random,
abstract_code: obj.abstract_code,
name: obj.name,
description: obj.description,
start_datetime: obj.start_datetime,
end_datetime: obj.end_datetime,
passcode: obj.passcode,
hide_event_launcher: obj.hide_event_launcher,
enable: obj.enable,
hide: obj.hide,
priority: obj.priority,
sort: obj.sort,
group: obj.group,
notes: obj.notes,
created_on: obj.created_on,
updated_on: obj.updated_on,
// From SQL view
event_session_code: obj.event_session_code,
event_session_name: obj.event_session_name,
// A key value list of the presenters
// event_presenter_kv: obj.event_presenter_kv,
});
// console.log(`Put obj with ID: ${obj.event_presentation_id_random} or ${id_random}`);
} catch (error) {
let status = `Failed to put ${obj.event_presentation_id_random}: ${error}`;
console.log(status);
}
// const id_random = await db_events.presentations.put(obj);
// console.log(`Put obj with ID: ${obj.event_presentation_id_random}`);
});
return true;
}
}

View File

@@ -0,0 +1,687 @@
import type { key_val } from '$lib/ae_stores';
import { api } from '$lib/api';
import { db_events } from "$lib/db_events";
import { load_ae_obj_li__event_file } from "$lib/ae_events__event_file";
let ae_promises: key_val = {};
// Updated 2024-10-08
export async function load_ae_obj_id__event_presenter(
{
api_cfg,
event_presenter_id,
inc_file_li = false,
try_cache = true,
log_lvl = 0
}: {
api_cfg: any,
event_presenter_id: string,
inc_file_li?: boolean,
try_cache?: boolean,
log_lvl?: number
}
) {
console.log(`*** load_ae_obj_id__event_presenter() *** event_presenter_id=${event_presenter_id}`);
let params = {};
ae_promises.load__event_presenter_obj = await api.get_ae_obj_id_crud({
api_cfg: api_cfg,
obj_type: 'event_presenter',
obj_id: event_presenter_id, // NOTE: This is the FQDN, not normally the ID.
use_alt_table: true, // NOTE: This will use the table_name_alt value instead of the table_name value in the API config.
use_alt_base: false, // NOTE: This will use the base_name_alt value instead of the base_name value
params: params,
log_lvl: log_lvl
})
.then(function (event_presenter_obj_get_result) {
if (event_presenter_obj_get_result) {
if (try_cache) {
// This is expecting a list
db_save_ae_obj_li__event_presenter({
obj_type: 'event_presenter',
obj_li: [event_presenter_obj_get_result]
});
}
return event_presenter_obj_get_result;
} else {
console.log('No results returned.');
return null;
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
});
if (inc_file_li) {
// Load the files for the presenter
if (log_lvl) {
console.log(`Need to load the file list for the presenter now.`);
}
let load_event_file_obj_li = load_ae_obj_li__event_file({
api_cfg: api_cfg,
for_obj_type: 'event_presenter',
for_obj_id: event_presenter_id,
params: {qry__enabled: 'all', qry__limit: 25},
try_cache: try_cache,
log_lvl: log_lvl
})
.then((event_file_obj_li) => {
if (log_lvl) {
console.log(`event_file_obj_li = `, event_file_obj_li);
}
return event_file_obj_li;
});
if (log_lvl) {
console.log(`event_file_obj_li = `, load_event_file_obj_li);
}
ae_promises.load__event_presenter_obj.event_file_li = load_event_file_obj_li;
}
return ae_promises.load__event_presenter_obj;
}
// Updated 2024-10-08
export async function load_ae_obj_li__event_presenter(
{
api_cfg,
for_obj_type,
for_obj_id,
inc_file_li = false,
order_by_li = {'priority': 'DESC', 'sort': 'DESC', 'given_name': 'ASC', 'family_name': 'ASC', 'updated_on': 'DESC', 'created_on': 'DESC'},
params = {},
try_cache = true,
log_lvl = 0
}: {
api_cfg: any,
for_obj_type: string,
for_obj_id: string,
inc_file_li?: boolean,
order_by_li?: key_val,
params?: key_val,
try_cache?: boolean,
log_lvl?: number
}
) {
if (log_lvl) {
console.log(`*** load_ae_obj_li__event_presenter() *** for_obj_type=${for_obj_type} for_obj_id=${for_obj_id}`);
}
let enabled: string = (params.qry__enabled ?? 'enabled'); // all, disabled, enabled
let hidden: string = (params.qry__hidden ?? 'not_hidden'); // all, hidden, not_hidden
let limit: number = (params.qry__limit ?? 99); // 99
let offset: number = (params.qry__offset ?? 0); // 0
let params_json: key_val = {};
// console.log('params_json:', params_json);
ae_promises.load__event_presenter_obj_li = await api.get_ae_obj_li_for_obj_id_crud({
api_cfg: api_cfg,
obj_type: 'event_presenter',
for_obj_type: for_obj_type,
for_obj_id: for_obj_id,
use_alt_table: true, // NOTE: This will use the table_name_alt value instead of the table_name value in the API config.
use_alt_base: false, // NOTE: This will use the base_name_alt value instead of the base_name value
enabled: enabled,
hidden: hidden,
order_by_li: order_by_li,
limit: limit,
offset: offset,
params_json: params_json,
params: params,
log_lvl: log_lvl
})
.then(function (event_presenter_obj_li_get_result) {
if (event_presenter_obj_li_get_result) {
if (try_cache) {
db_save_ae_obj_li__event_presenter({
obj_type: 'event_presenter',
obj_li: event_presenter_obj_li_get_result
});
}
return event_presenter_obj_li_get_result;
} else {
return [];
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
});
if (log_lvl) {
console.log('ae_promises.load__event_presenter_obj_li:', ae_promises.load__event_presenter_obj_li);
}
if (inc_file_li) {
// Load the files for the presenters
if (log_lvl) {
console.log(`Need to load the file list for each presenter now.`);
}
for (let i = 0; i < ae_promises.load__event_presenter_obj_li.length; i++) {
let event_presenter_obj = ae_promises.load__event_presenter_obj_li[i];
let event_presenter_id = event_presenter_obj.event_presenter_id_random;
let load_event_file_obj_li = load_ae_obj_li__event_file({
api_cfg: api_cfg,
for_obj_type: 'event_presenter',
for_obj_id: event_presenter_id,
params: {qry__enabled: 'all', qry__limit: 25},
try_cache: try_cache,
log_lvl: log_lvl
})
.then((event_file_obj_li) => {
if (log_lvl) {
console.log(`event_file_obj_li = `, event_file_obj_li);
}
return event_file_obj_li;
});
if (log_lvl) {
console.log(`event_file_obj_li = `, load_event_file_obj_li);
}
// ae_promises.load__event_presenter_obj.event_file_li = load_event_file_obj_li;
}
}
return ae_promises.load__event_presenter_obj_li;
}
// Updated 2024-08-07
export async function delete_ae_obj_id__event_presenter(
{
api_cfg,
event_presenter_id,
method = 'delete', // 'delete', 'disable', 'hide'
params = {},
log_lvl = 0
}: {
api_cfg: any,
event_presenter_id: string,
method?: string,
params?: key_val,
log_lvl?: number
}
) {
if (log_lvl) {
console.log(`*** delete_ae_obj_id__event_presenter() *** event_presenter_id=${event_presenter_id}`);
}
ae_promises.delete__event_presenter_obj = await api.delete_ae_obj_id_crud({
api_cfg: api_cfg,
obj_type: 'event_presenter',
obj_id: event_presenter_id, // NOTE: This is the FQDN, not normally the ID.
key: api_cfg.api_crud_super_key,
params: params,
method: method,
log_lvl: log_lvl
})
.then(function (event_presenter_obj_delete_result) {
if (event_presenter_obj_delete_result) {
// db_save_ae_obj_li__event_presenter({obj_type: 'event_presenter', obj_li: [event_presenter_obj_delete_result]});
return event_presenter_obj_delete_result;
} else {
return null;
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
})
.finally(function () {
db_events.presenters.delete(event_presenter_id);
});
if (log_lvl) {
console.log('ae_promises.delete__event_presenter_obj:', ae_promises.delete__event_presenter_obj);
}
return ae_promises.delete__event_presenter_obj;
}
// Updated 2024-06-24
export async function create_ae_obj__event_presenter(
{
api_cfg,
event_id,
event_session_id,
event_presentation_id,
data_kv,
params = {},
log_lvl = 0
}: {
api_cfg: any,
event_id: string,
event_session_id: string,
event_presentation_id: string,
data_kv: key_val,
params?: key_val,
log_lvl?: number
}
) {
if (log_lvl) {
console.log(`*** create_ae_obj__event_presenter() *** event_id=${event_id} event_session_id=${event_session_id} event_presentation_id=${event_presentation_id}`);
}
ae_promises.create__event_presenter = await api.create_ae_obj_crud({
api_cfg: api_cfg,
obj_type: 'event_presenter',
fields: {
event_id_random: event_id,
event_session_id_random: event_session_id,
event_presentation_id_random: event_presentation_id,
...data_kv
},
key: api_cfg.api_crud_super_key,
params: params,
return_obj: true,
log_lvl: log_lvl
})
.then(function (event_presenter_obj_create_result) {
if (event_presenter_obj_create_result) {
db_save_ae_obj_li__event_presenter(
{
obj_type: 'event_presenter', obj_li: [event_presenter_obj_create_result]
});
return event_presenter_obj_create_result;
} else {
return null;
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
})
.finally(function () {
});
if (log_lvl) {
console.log('ae_promises.create__event_presenter:', ae_promises.create__event_presenter);
}
return ae_promises.create__event_presenter;
}
// Updated 2024-09-13
export async function update_ae_obj__event_presenter(
{
api_cfg,
event_presenter_id,
data_kv,
params = {},
try_cache = true,
log_lvl = 0
}: {
api_cfg: any,
event_presenter_id: string,
data_kv: key_val,
params?: key_val,
try_cache?: boolean,
log_lvl?: number
}
) {
if (log_lvl) {
console.log(`*** update_ae_obj__event_presenter() *** event_presenter_id=${event_presenter_id}`, data_kv);
}
ae_promises.update__event_presenter_obj = await api.update_ae_obj_id_crud({
api_cfg: api_cfg,
obj_type: 'event_presenter',
obj_id: event_presenter_id,
fields: data_kv,
key: api_cfg.api_crud_super_key,
params: params,
return_obj: true,
log_lvl: log_lvl
})
.then(function (event_presenter_obj_update_result) {
if (event_presenter_obj_update_result) {
if (try_cache) {
db_save_ae_obj_li__event_presenter({
obj_type: 'event_presenter',
obj_li: [event_presenter_obj_update_result]
});
}
return event_presenter_obj_update_result;
} else {
return null;
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
})
.finally(function () {
});
if (log_lvl) {
console.log('ae_promises.update__event_presenter_obj:', ae_promises.update__event_presenter_obj);
}
return ae_promises.update__event_presenter_obj;
}
// Updated 2024-07-11
export async function search__event_presenter(
{
api_cfg,
event_id,
agree = null,
biography = null,
fulltext_search_qry_str,
ft_presenter_search_qry_str,
like_search_qry_str = null,
like_presentation_search_qry_str = null,
like_presenter_search_qry_str = null,
order_by_li = {'priority': 'DESC', 'sort': 'DESC', 'given_name': 'ASC', 'family_name': 'ASC', 'email': 'ASC', 'updated_on': 'DESC', 'created_on': 'DESC'},
params = {},
try_cache = true,
log_lvl = 0
}: {
api_cfg: any,
event_id: any,
agree?: null|boolean,
biography?: null|boolean,
fulltext_search_qry_str?: null|string,
ft_presenter_search_qry_str?: null|string,
like_search_qry_str?: null|string,
like_presentation_search_qry_str?: null|string,
like_presenter_search_qry_str?: null|string,
order_by_li?: key_val,
params?: any,
try_cache?: boolean,
log_lvl?: number
}
) {
if (log_lvl) {
console.log(`*** search__event_presenter() *** event_id=${event_id}`);
}
let enabled: string = (params.qry__enabled ?? 'enabled'); // all, disabled, enabled
let hidden: string = (params.qry__hidden ?? 'not_hidden'); // all, hidden, not_hidden
let limit: number = (params.qry__limit ?? 25); // 99
let offset: number = (params.qry__offset ?? 0); // 0
let params_json: key_val = {};
// if (!fulltext_search_qry_str && !like_search_qry_str) {
// console.log('No search string provided!!!');
// return false; // Returning false instead of [] because no search was performed.
// }
if (fulltext_search_qry_str || ft_presenter_search_qry_str) {
params_json['ft_qry'] = {};
if (fulltext_search_qry_str && fulltext_search_qry_str.length > 2) {
params_json['ft_qry']['default_qry_str'] = fulltext_search_qry_str;
}
if (ft_presenter_search_qry_str && ft_presenter_search_qry_str.length > 2) {
params_json['ft_qry']['event_presenter_li_qry_str'] = ft_presenter_search_qry_str;
}
}
// Use the AND (AND LIKE) query
// if (like_search_qry_str || like_presenter_search_qry_str) {
// params_json['and_like'] = {};
// if (like_search_qry_str && like_search_qry_str.length > 2) {
// params_json['and_like']['default_qry_str'] = like_search_qry_str;
// }
// if (like_presenter_search_qry_str && like_presenter_search_qry_str.length > 2) {
// params_json['and_like']['event_presenter_li_qry_str'] = like_presenter_search_qry_str;
// }
// }
// Use the AND (OR LIKE) query
if (like_search_qry_str || like_presentation_search_qry_str || like_presenter_search_qry_str) {
params_json['or_like'] = {};
if (like_search_qry_str && like_search_qry_str.length > 2) {
params_json['or_like']['default_qry_str'] = like_search_qry_str;
}
if (like_presentation_search_qry_str && like_presentation_search_qry_str.length > 2) {
params_json['or_like']['event_presentation_li_qry_str'] = like_presentation_search_qry_str;
}
if (like_presenter_search_qry_str && like_presenter_search_qry_str.length > 2) {
params_json['or_like']['event_presenter_li_qry_str'] = like_presenter_search_qry_str;
}
}
params_json['and_qry'] = {};
if (agree) {
params_json['and_qry']['agree'] = agree;
}
if (biography) {
params_json['and_qry']['biography_check'] = biography;
}
ae_promises.load__event_presenter_obj_li = await api.get_ae_obj_li_for_obj_id_crud({
api_cfg: api_cfg,
obj_type: 'event_presenter',
for_obj_type: 'event',
for_obj_id: event_id,
use_alt_table: true, // NOTE: We want to use the alt table for session searching
use_alt_base: false,
enabled: enabled,
hidden: hidden,
order_by_li: order_by_li,
limit: limit,
offset: offset,
params_json: params_json,
params: params,
log_lvl: log_lvl
})
.then(function (event_presenter_obj_li_get_result) {
if (event_presenter_obj_li_get_result) {
if (try_cache) {
db_save_ae_obj_li__event_presenter({
obj_type: 'event_presenter',
obj_li: event_presenter_obj_li_get_result
});
}
db_save_ae_obj_li__event_presenter({obj_type: 'event_presenter', obj_li: event_presenter_obj_li_get_result});
return event_presenter_obj_li_get_result;
} else {
return [];
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
})
.finally(function () {
});
if (log_lvl) {
console.log('ae_promises.load__event_presenter_obj_li:', ae_promises.load__event_presenter_obj_li);
}
return ae_promises.load__event_presenter_obj_li;
}
// Updated 2024-06-10
export function db_save_ae_obj_li__event_presenter(
{
obj_type,
obj_li,
log_lvl = 0
}: {
obj_type: string,
obj_li: any,
log_lvl?: number
}
) {
if (log_lvl) {
console.log(`*** db_save_ae_obj_li__event_presenter() ***`);
}
if (obj_li && obj_li.length) {
obj_li.forEach(async function (obj: any) {
if (log_lvl) {
console.log(`ae_obj ${obj_type}:`, obj);
}
try {
const id_random = await db_events.presenters.put({
id: obj.event_presenter_id_random,
// id_random: obj.event_presenter_id_random,
event_presenter_id: obj.event_presenter_id_random,
event_presenter_id_random: obj.event_presenter_id_random,
external_id: obj.external_id,
code: obj.code,
// for_type: obj.for_type,
// for_id_random: obj.for_id_random,
event_id: obj.event_id_random,
event_id_random: obj.event_id_random,
event_session_id: obj.event_session_id_random,
event_session_id_random: obj.event_session_id_random,
event_presentation_id: obj.event_presentation_id_random,
event_presentation_id_random: obj.event_presentation_id_random,
event_person_id: obj.event_person_id_random,
event_person_id_random: obj.event_person_id_random,
person_id: obj.person_id_random,
person_id_random: obj.person_id_random,
person_profile_id: obj.person_profile_id_random,
person_profile_id_random: obj.person_profile_id_random, // The new table person_profile will be used soon...
pronouns: obj.pronouns,
informal_name: obj.informal_name,
title_names: obj.title_names,
given_name: obj.given_name,
middle_name: obj.middle_name,
family_name: obj.family_name,
designations: obj.designations,
professional_title: obj.professional_title,
full_name: obj.full_name,
affiliations: obj.affiliations,
email: obj.email,
biography: obj.biography,
agree: obj.agree,
comments: obj.comments,
passcode: obj.passcode,
hide_event_launcher: obj.hide_event_launcher,
data_json: obj.data_json,
enable: obj.enable,
hide: obj.hide,
priority: obj.priority,
sort: obj.sort,
group: obj.group,
notes: obj.notes,
created_on: obj.created_on,
updated_on: obj.updated_on,
// From SQL view
file_count: obj.file_count,
event_session_code: obj.event_session_code,
event_session_name: obj.event_session_name,
event_session_start_datetime: obj.event_session_start_datetime,
event_presentation_code: obj.event_presentation_code,
event_presentation_name: obj.event_presentation_name,
event_presentation_start_datetime: obj.event_presentation_start_datetime,
person_external_id: obj.person_external_id,
person_external_sys_id: obj.person_external_sys_id,
person_given_name: obj.person_given_name,
person_family_name: obj.person_family_name,
person_full_name: obj.person_full_name,
person_professional_title: obj.person_professional_title,
person_affiliations: obj.person_affiliations,
person_primary_email: obj.person_primary_email,
person_passcode: obj.person_passcode,
});
// console.log(`Put obj with ID: ${obj.event_presenter_id_random} or ${id_random}`);
} catch (error) {
let status = `Failed to put ${obj.event_presenter_id_random}: ${error}`;
console.log(status);
}
// const id_random = await db_events.presenters.put(obj);
// console.log(`Put obj with ID: ${obj.event_presenter_id_random}`);
});
return true;
}
return false;
}
// Updated 2024-08-07
export async function email_sign_in__event_presenter (
{
api_cfg,
to_email,
to_name,
base_url,
person_id,
person_passcode,
event_session_id,
event_presentation_id,
event_presenter_id,
session_name,
presentation_name,
log_lvl = 0
}: {
api_cfg: any,
to_email: string,
to_name: string,
base_url: string,
person_id: string,
person_passcode: string,
event_session_id: string,
event_presentation_id: string,
event_presenter_id: string,
session_name: string,
presentation_name: string,
log_lvl?: number
}
) {
if (log_lvl) {
console.log(`*** email_sign_in__event_presenter() *** to_email=${to_email} to_name=${to_name} person_id=${person_id} person_passcode=${person_passcode} presentation_id=${event_presentation_id} presenter_id=${event_presenter_id}`);
}
let subject = `LCI Congress 2024 - Pres Mgmt Hub Sign In Link for ${session_name} (ID: ${event_session_id})`;
let sign_in_url = encodeURI(`${base_url}/events_pres_mgmt/session/${event_session_id}?person_id=${person_id}&person_pass=${person_passcode}&presentation_id=${event_presentation_id}&presenter_id=${event_presenter_id}`)
let body_html = `
<div>${to_name},
<p>Your link to sign into the presentation management hub for LCI Congress 2024 is below. If you did not request this, please delete and ignore this email. If you need to make any changes or updates to your submission, you may use this link again later.</p>
</div>
<div>
<strong>26th Annual Lean Construction Congress (2024)</strong>:<br>
<p>
Session Name: ${session_name}<br>
Session ID: ${event_session_id}<br>
Presentation Name: ${presentation_name}<br>
Presentation ID: ${event_presentation_id}
</p>
<p>Use this link to view or update your LCI 2024 presentation information.<br>
Copy and paste link: <a href="${sign_in_url}">${sign_in_url}</a></p>
</div>`;
api.send_email({
api_cfg: api_cfg,
from_email: 'noreply+presmgmt@oneskyit.com',
from_name: 'LCI 2024 Pres Mgmt Hub',
to_email: to_email,
subject: subject,
body_html: body_html,
});
}

View File

@@ -0,0 +1,821 @@
import type { key_val } from '$lib/ae_stores';
import { api } from '$lib/api';
import { db_events } from "$lib/db_events";
import { load_ae_obj_li__event_file } from "$lib/ae_events__event_file";
import { load_ae_obj_li__event_presentation } from "$lib/ae_events__event_presentation";
let ae_promises: key_val = {};
// Updated 2024-08-09
export async function load_ae_obj_id__event_session(
{
api_cfg,
event_session_id,
inc_file_li = false,
inc_presentation_li = false,
inc_presenter_li = false,
try_cache = true,
log_lvl = 0
}: {
api_cfg: any,
event_session_id: string,
inc_file_li?: boolean,
inc_presentation_li?: boolean,
inc_presenter_li?: boolean,
try_cache?: boolean,
log_lvl?: number
}
) {
console.log(`*** load_ae_obj_id__event_session() *** event_session_id=${event_session_id}`);
let params = {};
// $events_sess.badges.status_load__event_session_obj = 'loading';
ae_promises.load__event_session_obj = await api.get_ae_obj_id_crud({
api_cfg: api_cfg,
obj_type: 'event_session',
obj_id: event_session_id, // NOTE: This is the FQDN, not normally the ID.
use_alt_table: true, // NOTE: This will use the table_name_alt value instead of the table_name value in the API config.
use_alt_base: false, // NOTE: This will use the base_name_alt value instead of the base_name value in the API config.
params: params,
log_lvl: log_lvl
})
.then(function (event_session_obj_get_result) {
if (event_session_obj_get_result) {
if (try_cache) {
// This is expecting a list
db_save_ae_obj_li__event_session({
obj_type: 'event_session',
obj_li: [event_session_obj_get_result]
});
}
return event_session_obj_get_result;
} else {
console.log('No results returned.');
return null;
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
});
if (log_lvl) {
console.log('ae_promises.load__event_session_obj:', ae_promises?.load__event_session_obj);
}
if (ae_promises?.load__event_session_obj === null) {
console.log('No results returned.');
return null;
}
if (inc_file_li) {
// Load the files for the session
if (log_lvl) {
console.log(`Need to load the file list for the session now`);
}
let load_event_file_obj_li = load_ae_obj_li__event_file({
api_cfg: api_cfg,
for_obj_type: 'event_session',
for_obj_id: event_session_id,
params: {qry__enabled: 'all', qry__limit: 15},
try_cache: try_cache,
log_lvl: log_lvl
})
.then((event_file_obj_li) => {
if (log_lvl) {
console.log(`event_file_obj_li = `, event_file_obj_li);
}
return event_file_obj_li;
});
if (log_lvl) {
console.log(`load_event_file_obj_li = `, load_event_file_obj_li);
}
ae_promises.load__event_session_obj.event_file_li = load_event_file_obj_li;
}
if (inc_presentation_li) {
// Load the presentations for the session
if (log_lvl) {
console.log(`Need to load the presentation list for the session now`);
}
let load_event_presentation_obj_li = load_ae_obj_li__event_presentation({
api_cfg: api_cfg,
for_obj_type: 'event_session',
for_obj_id: event_session_id,
inc_file_li: inc_file_li,
inc_presenter_li: inc_presenter_li,
params: {qry__enabled: 'all', qry__limit: 25},
try_cache: try_cache,
log_lvl: log_lvl
})
.then((event_presentation_obj_li) => {
if (log_lvl) {
console.log(`event_presentation_obj_li = `, event_presentation_obj_li);
}
// if (try_cache) {
// console.log(`ae_promises.load__event_session_obj = `, ae_promises.load__event_session_obj);
// ae_promises.load__event_session_obj.event_presentation_li = event_presentation_obj_li;
// // Re-save the session object with the new presentation list
// db_save_ae_obj_li__event_session({
// obj_type: 'event_session',
// obj_li: [ae_promises.load__event_session_obj]
// });
// }
return event_presentation_obj_li;
});
if (log_lvl) {
console.log(`event_presentation_obj_li = `, load_event_presentation_obj_li);
}
ae_promises.load__event_session_obj.event_presentation_li = load_event_presentation_obj_li;
}
return ae_promises.load__event_session_obj;
}
// Updated 2024-08-09
export async function load_ae_obj_li__event_session(
{
api_cfg,
for_obj_type,
for_obj_id,
inc_file_li = false,
inc_presentation_li = false,
inc_presenter_li = false,
order_by_li = {'priority': 'DESC', 'sort': 'DESC', 'start_datetime': 'ASC', 'name': 'ASC', 'updated_on': 'DESC', 'created_on': 'DESC'},
params = {},
try_cache = true,
log_lvl = 0
}: {
api_cfg: any,
for_obj_type: string,
for_obj_id: string,
inc_file_li?: boolean,
inc_presentation_li?: boolean,
inc_presenter_li?: boolean,
order_by_li?: key_val,
params?: key_val,
try_cache?: boolean,
log_lvl?: number
}
) {
console.log(`*** load_ae_obj_li__event_session() *** for_obj_type=${for_obj_type} for_obj_id=${for_obj_id}`);
let enabled: string = (params.qry__enabled ?? 'enabled'); // all, disabled, enabled
let hidden: string = (params.qry__hidden ?? 'not_hidden'); // all, hidden, not_hidden
let limit: number = (params.qry__limit ?? 99); // 99
let offset: number = (params.qry__offset ?? 0); // 0
let params_json: key_val = {};
// console.log('params_json:', params_json);
ae_promises.load__event_session_obj_li = await api.get_ae_obj_li_for_obj_id_crud({
api_cfg: api_cfg,
obj_type: 'event_session',
for_obj_type: for_obj_type,
for_obj_id: for_obj_id,
use_alt_table: true, // NOTE: This will use the table_name_alt value instead of the table_name value in the API config.
use_alt_base: false, // NOTE: This will use the base_name_alt value instead of the base_name value
enabled: enabled,
hidden: hidden,
order_by_li: order_by_li,
limit: limit,
offset: offset,
params_json: params_json,
params: params,
log_lvl: log_lvl
})
.then(function (event_session_obj_li_get_result) {
if (event_session_obj_li_get_result) {
if (try_cache) {
db_save_ae_obj_li__event_session({
obj_type: 'event_session',
obj_li: event_session_obj_li_get_result
});
}
return event_session_obj_li_get_result;
} else {
return [];
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
});
if (log_lvl) {
console.log('ae_promises.load__event_session_obj_li:', ae_promises.load__event_session_obj_li);
}
if (inc_file_li) {
// Load the files for the sessions
if (log_lvl) {
console.log(`Need to load the file list for each session now`);
}
for (let i = 0; i < ae_promises.load__event_session_obj_li.length; i++) {
let event_session_obj = ae_promises.load__event_session_obj_li[i];
let event_session_id = event_session_obj.event_session_id_random;
let load_event_file_obj_li = load_ae_obj_li__event_file({
api_cfg: api_cfg,
for_obj_type: 'event_session',
for_obj_id: event_session_id,
params: {qry__enabled: enabled, qry__limit: limit},
try_cache: try_cache,
log_lvl: log_lvl
})
.then((event_file_obj_li) => {
if (log_lvl) {
console.log(`event_file_obj_li = `, event_file_obj_li);
}
return event_file_obj_li;
});
if (log_lvl) {
console.log(`load_event_file_obj_li = `, load_event_file_obj_li);
}
}
}
if (inc_presentation_li) {
// Load the presentations for the sessions
if (log_lvl) {
console.log(`Need to load the presentation list for each session now`);
}
for (let i = 0; i < ae_promises.load__event_session_obj_li.length; i++) {
let event_session_obj = ae_promises.load__event_session_obj_li[i];
let event_session_id = event_session_obj.event_session_id_random;
let load_event_presentation_obj_li = load_ae_obj_li__event_presentation({
api_cfg: api_cfg,
for_obj_type: 'event_session',
for_obj_id: event_session_id,
inc_file_li: inc_file_li,
inc_presenter_li: inc_presenter_li,
params: {qry__enabled: enabled, qry__limit: limit},
try_cache: try_cache,
log_lvl: log_lvl
})
.then((event_presentation_obj_li) => {
if (log_lvl) {
console.log(`event_presentation_obj_li = `, event_presentation_obj_li);
}
// if (try_cache) {
// console.log(`event_session_obj = `, event_session_obj);
// event_session_obj.event_presentation_li = event_presentation_obj_li;
// // Re-save the session object with the new presentation list
// db_save_ae_obj_li__event_session({
// obj_type: 'event_session',
// obj_li: event_session_obj
// });
// }
return event_presentation_obj_li;
});
if (log_lvl) {
console.log(`load_event_presentation_obj_li = `, load_event_presentation_obj_li);
}
}
}
return ae_promises.load__event_session_obj_li;
}
// Updated 2024-09-25
export async function create_ae_obj__event_session(
{
api_cfg,
event_id,
data_kv,
params={},
log_lvl=0
}: {
api_cfg: any,
event_id: string,
data_kv: key_val,
params?: key_val,
log_lvl?: number
}
) {
console.log(`*** create_ae_obj__event_session() *** event_id=${event_id}`);
ae_promises.create__event_session = await api.create_ae_obj_crud({
api_cfg: api_cfg,
obj_type: 'event_session',
fields: {
event_id_random: event_id,
...data_kv
},
key: api_cfg.api_crud_super_key,
params: params,
return_obj: true,
log_lvl: log_lvl
})
.then(function (event_session_obj_create_result) {
if (event_session_obj_create_result) {
db_save_ae_obj_li__event_session(
{
obj_type: 'event_session',
obj_li: [event_session_obj_create_result]
});
return event_session_obj_create_result;
} else {
return null;
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
})
.finally(function () {
});
if (log_lvl) {
console.log('ae_promises.create__event_session:', ae_promises.create__event_session);
}
return ae_promises.create__event_session;
}
// Updated 2024-09-13
export async function update_ae_obj__event_session(
{
api_cfg,
event_session_id,
data_kv,
params = {},
try_cache = true,
log_lvl = 0
}: {
api_cfg: any,
event_session_id: string,
data_kv: key_val,
params?: key_val,
try_cache?: boolean,
log_lvl?: number
}
) {
if (log_lvl) {
console.log(`*** update_ae_obj__event_session() *** event_session_id=${event_session_id}`, data_kv);
}
// ae_promises.update__event_session_obj = 'test';
ae_promises.update__event_session_obj = await api.update_ae_obj_id_crud({
api_cfg: api_cfg,
obj_type: 'event_session',
obj_id: event_session_id,
fields: data_kv,
key: api_cfg.api_crud_super_key,
params: params,
return_obj: true,
log_lvl: log_lvl
})
.then(function (event_session_obj_update_result) {
if (event_session_obj_update_result) {
if (try_cache) {
db_save_ae_obj_li__event_session({
obj_type: 'event_session', obj_li: [event_session_obj_update_result]
});
}
return event_session_obj_update_result;
} else {
return null;
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
})
.finally(function () {
});
if (log_lvl) {
console.log('ae_promises.update__event_session_obj:', ae_promises.update__event_session_obj);
}
return ae_promises.update__event_session_obj;
}
// This new function is using CRUD v2. This should allow for more flexibility in the queries.
// Updated 2024-08-14
export async function qry__event_session(
{
api_cfg,
event_id,
qry_str,
qry_files,
qry_start_datetime, // Example greater than: '2024-10-24'
enabled = 'enabled',
hidden = 'not_hidden',
limit = 50,
offset = 0,
params = {},
try_cache = true,
log_lvl = 0
}: {
api_cfg: any,
event_id: any,
qry_str?: string,
qry_files?: null|boolean,
qry_start_datetime?: null|string, // Greater than this datetime
enabled?: string, // all, disabled, enabled
hidden?: string, // all, hidden, not_hidden
limit?: number,
offset?: number,
params?: any,
try_cache?: boolean,
log_lvl?: number
}
) {
console.log(`*** qry__event_session() *** event_id=${event_id} qry_str=${qry_str}`);
// let enabled: string = (params.qry__enabled ?? 'enabled'); // all, disabled, enabled
// let hidden: string = (params.qry__hidden ?? 'not_hidden'); // all, hidden, not_hidden
// let limit: number = (params.qry__limit ?? 25); // 99
// let offset: number = (params.qry__offset ?? 0); // 0
let params_json: key_val = {};
// if (qry_str && qry_str.length > 2) {
// params_json['ft_qry'] = {};
// params_json['ft_qry']['default_qry_str'] = qry_str;
// }
params_json['qry'] = [];
if (qry_files === true) {
let qry_param =
{
type: "AND",
field: "file_count_all",
operator: ">",
value: 0
};
params_json['qry'].push(qry_param);
} else if (qry_files === false) {
let qry_param =
{
type: "AND",
field: "file_count_all",
operator: "IS",
value: null
};
params_json['qry'].push(qry_param);
}
if (qry_start_datetime) {
let qry_param =
{
type: "AND",
field: "start_datetime",
operator: ">",
value: qry_start_datetime
};
params_json['qry'].push(qry_param);
}
let order_by_li = {'priority': 'DESC', 'sort': 'DESC', 'start_datetime': 'ASC', 'name': 'ASC', 'updated_on': 'DESC', 'created_on': 'DESC'};
ae_promises.load__event_session_obj_li = await api.get_ae_obj_li_for_obj_id_crud_v2({
api_cfg: api_cfg,
obj_type: 'event_session',
for_obj_type: 'event',
for_obj_id: event_id,
use_alt_tbl: true, // NOTE: We want to use the alt table for session searching
use_alt_mdl: false,
use_alt_exp: false,
enabled: enabled,
hidden: hidden,
order_by_li: order_by_li,
limit: limit,
offset: offset,
params_json: params_json,
params: params,
log_lvl: log_lvl
})
.then(function (event_session_obj_li_get_result) {
if (event_session_obj_li_get_result) {
db_save_ae_obj_li__event_session({
obj_type: 'event_session',
obj_li: event_session_obj_li_get_result
});
return event_session_obj_li_get_result;
} else {
return [];
}
});
if (log_lvl) {
console.log('ae_promises.load__event_session_obj_li:', ae_promises.load__event_session_obj_li);
}
return ae_promises.load__event_session_obj_li;
}
// Updated 2024-09-13
export async function search__event_session(
{
api_cfg,
event_id,
poc_agree = null,
fulltext_search_qry_str,
ft_presenter_search_qry_str,
like_search_qry_str = null,
like_presentation_search_qry_str = null,
like_presenter_search_qry_str = null,
file_count = false, // If true then only show those that have a file count
location_name = null,
params = {},
try_cache = true,
log_lvl = 0
}: {
api_cfg: any,
event_id: any,
poc_agree?: null|boolean,
fulltext_search_qry_str?: null|string,
ft_presenter_search_qry_str?: null|string,
like_search_qry_str?: null|string,
like_presentation_search_qry_str?: null|string,
like_presenter_search_qry_str?: null|string,
file_count?: boolean,
location_name?: null|string,
params?: any,
try_cache?: boolean,
log_lvl?: number
}
) {
console.log(`*** search__event_session() *** event_id=${event_id}`);
let enabled: string = (params.qry__enabled ?? 'enabled'); // all, disabled, enabled
let hidden: string = (params.qry__hidden ?? 'not_hidden'); // all, hidden, not_hidden
let limit: number = (params.qry__limit ?? 25); // 99
let offset: number = (params.qry__offset ?? 0); // 0
let params_json: key_val = {};
// if (!fulltext_search_qry_str && !like_search_qry_str) {
// console.log('No search string provided!!!');
// return false; // Returning false instead of [] because no search was performed.
// }
if (fulltext_search_qry_str || ft_presenter_search_qry_str) {
params_json['ft_qry'] = {};
if (fulltext_search_qry_str && fulltext_search_qry_str.length > 2) {
params_json['ft_qry']['default_qry_str'] = fulltext_search_qry_str;
}
if (ft_presenter_search_qry_str && ft_presenter_search_qry_str.length > 2) {
params_json['ft_qry']['event_presenter_li_qry_str'] = ft_presenter_search_qry_str;
}
}
// Use the AND (AND LIKE) query
// if (like_search_qry_str || like_presenter_search_qry_str) {
// params_json['and_like'] = {};
// if (like_search_qry_str && like_search_qry_str.length > 2) {
// params_json['and_like']['default_qry_str'] = like_search_qry_str;
// }
// if (like_presenter_search_qry_str && like_presenter_search_qry_str.length > 2) {
// params_json['and_like']['event_presenter_li_qry_str'] = like_presenter_search_qry_str;
// }
// }
// Use the AND (OR LIKE) query
if (like_search_qry_str || like_presentation_search_qry_str || like_presenter_search_qry_str) {
params_json['or_like'] = {};
if (like_search_qry_str && like_search_qry_str.length > 2) {
params_json['or_like']['default_qry_str'] = like_search_qry_str;
}
if (like_presentation_search_qry_str && like_presentation_search_qry_str.length > 2) {
params_json['or_like']['event_presentation_li_qry_str'] = like_presentation_search_qry_str;
}
if (like_presenter_search_qry_str && like_presenter_search_qry_str.length > 2) {
params_json['or_like']['event_presenter_li_qry_str'] = like_presenter_search_qry_str;
}
}
params_json['and_qry'] = {};
if (poc_agree) {
params_json['and_qry']['poc_agree'] = poc_agree;
}
if (file_count) {
params_json['and_qry']['file_count'] = file_count;
}
// This should be using a like with surrounded by %'s
if (location_name) {
params_json['and_qry']['event_location_name'] = location_name;
}
let order_by_li = {'priority': 'DESC', 'sort': 'DESC', 'start_datetime': 'ASC', 'name': 'ASC', 'updated_on': 'DESC', 'created_on': 'DESC'};
ae_promises.load__event_session_obj_li = await api.get_ae_obj_li_for_obj_id_crud({
api_cfg: api_cfg,
obj_type: 'event_session',
for_obj_type: 'event',
for_obj_id: event_id,
use_alt_table: true, // NOTE: We want to use the alt table for session searching
use_alt_base: false,
enabled: enabled,
hidden: hidden,
order_by_li: order_by_li,
limit: limit,
offset: offset,
params_json: params_json,
params: params,
log_lvl: log_lvl
})
.then(function (event_session_obj_li_get_result) {
if (event_session_obj_li_get_result) {
if (try_cache) {
db_save_ae_obj_li__event_session({
obj_type: 'event_session',
obj_li: event_session_obj_li_get_result
});
}
return event_session_obj_li_get_result;
} else {
return [];
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
})
.finally(function () {
});
if (log_lvl) {
console.log('ae_promises.load__event_session_obj_li:', ae_promises.load__event_session_obj_li);
}
return ae_promises.load__event_session_obj_li;
}
// This function will loop through the event_session_obj_li and save each one to the DB.
export function db_save_ae_obj_li__event_session(
{
obj_type,
obj_li,
log_lvl = 0
}: {
obj_type: string,
obj_li: any,
log_lvl?: number
}
) {
if (log_lvl) {
console.log(`*** db_save_ae_obj_li__event_session() ***`);
}
if (obj_li && obj_li.length) {
obj_li.forEach(async function (obj: any) {
if (log_lvl) {
console.log(`ae_obj ${obj_type}:`, obj);
}
try {
const id_random = await db_events.sessions.put({
id: obj.event_session_id_random,
event_session_id: obj.event_session_id_random,
event_session_id_random: obj.event_session_id_random,
external_id: obj.external_id,
code: obj.code,
for_type: obj.for_type,
for_id: obj.for_id_id_random,
for_id_random: obj.for_id_random,
type_code: obj.type_code,
event_id: obj.event_id_random,
event_id_random: obj.event_id_random,
event_location_id: obj.event_location_id_random,
event_location_id_random: obj.event_location_id_random,
poc_person_id: obj.poc_person_id_random,
poc_person_id_random: obj.poc_person_id_random,
poc_agree: obj.poc_agree,
poc_kv_json: obj.poc_kv_json ?? {},
name: obj.name,
description: obj.description,
start_datetime: obj.start_datetime,
end_datetime: obj.end_datetime,
passcode: obj.passcode,
hide_event_launcher: obj.hide_event_launcher,
alert: obj.alert,
alert_msg: obj.alert_msg,
data_json: obj.data_json,
ux_mode: obj.ux_mode,
enable: obj.enable,
hide: obj.hide,
priority: obj.priority,
sort: obj.sort,
group: obj.group,
notes: obj.notes,
created_on: obj.created_on,
updated_on: obj.updated_on,
// From SQL view
file_count: obj.file_count,
file_count_all: obj.file_count_all,
internal_use_count: obj.internal_use_count,
event_file_id_li_json: obj.event_file_id_li_json,
poc_person_given_name: obj.poc_person_given_name,
poc_person_family_name: obj.poc_person_family_name,
poc_person_full_name: obj.poc_person_full_name,
poc_person_primary_email: obj.poc_person_primary_email,
poc_person_passcode: obj.poc_person_passcode,
event_name: obj.event_name,
event_location_code: obj.event_location_code,
event_location_name: obj.event_location_name,
// A key value list of the presentations
event_presentation_kv: obj.event_presentation_kv,
event_presentation_li: obj.event_presentation_li,
});
// console.log(`Put obj with ID: ${obj.event_session_id_random} or ${id_random}`);
} catch (error) {
let status = `Failed to put ${obj.event_session_id_random}: ${error}`;
console.log(status);
}
// const id_random = await db_events.sessions.put(obj);
// console.log(`Put obj with ID: ${obj.event_session_id_random}`);
});
return true;
}
}
// This is intended for the Point of Contact (POC) for the session.
// Updated 2024-07-01
export async function email_sign_in__event_session (
{
api_cfg,
to_email,
to_name,
base_url,
person_id,
person_passcode,
event_session_id,
session_name,
}: {
api_cfg: any,
to_email: string,
to_name: string,
base_url: string,
person_id: string,
person_passcode: string,
event_session_id: string,
session_name: string,
}
) {
console.log(`*** email_sign_in__event_session() *** to_email=${to_email} to_name=${to_name} person_id=${person_id} person_passcode=${person_passcode} session_id=${event_session_id}`);
let subject = `LCI Congress 2024 - Pres Mgmt Hub Sign In Link for ${session_name} (ID: ${event_session_id})`;
let sign_in_url = encodeURI(`${base_url}/events_pres_mgmt/session/${event_session_id}?person_id=${person_id}&person_pass=${person_passcode}&session_id=${event_session_id}`)
let body_html = `
<div>${to_name},
<p>Your link to sign into the presentation management hub as a session Champion for LCI Congress 2024 is below. If you did not request this, please delete and ignore this email. If you need to make any changes or updates to your submission, you may use this link again later.</p>
</div>
<div>
<strong>26th Annual Lean Construction Congress (2024)</strong>:<br>
<p>
Session Name: ${session_name}<br>
Session ID: ${event_session_id}
</p>
<p>Use this link to view or update your LCI 2024 session information.<br>
Copy and paste link: <a href="${sign_in_url}">${sign_in_url}</a></p>
</div>`;
api.send_email({
api_cfg: api_cfg,
from_email: 'noreply+presmgmt@oneskyit.com',
from_name: 'LCI 2024 Pres Mgmt Hub',
to_email: to_email,
subject: subject,
body_html: body_html,
});
}

View File

@@ -0,0 +1,564 @@
import type { key_val } from '$lib/ae_stores';
import { api } from '$lib/api';
import { db_events } from "$lib/db_events";
let ae_promises: key_val = {};
// Updated 2024-03
export async function handle_load_ae_obj_id__exhibit(
{
api_cfg,
exhibit_id,
try_cache=false,
log_lvl=0
}: {
api_cfg: any,
exhibit_id: string,
try_cache?: boolean,
log_lvl?: number
}
) {
console.log(`*** handle_load_ae_obj_id__exhibit() *** exhibit_id=${exhibit_id}`);
let params = {};
// $events_sess.exhibits.status_load__exhibit_obj = 'loading';
ae_promises.load__exhibit_obj = await api.get_ae_obj_id_crud({
api_cfg: api_cfg,
obj_type: 'event_exhibit',
obj_id: exhibit_id, // NOTE: This is the FQDN, not normally the ID.
use_alt_table: false, // NOTE: This will use the table_name_alt value instead of the table_name value in the API config.
use_alt_base: false, // NOTE: This will use the base_name_alt value instead of the base_name value in the API config.
params: params,
log_lvl: log_lvl
})
.then(function (exhibit_obj_get_result) {
if (exhibit_obj_get_result) {
// This is expecting a list
handle_db_save_ae_obj_li__exhibitor({obj_type: 'event_exhibit', obj_li: [exhibit_obj_get_result]});
return exhibit_obj_get_result;
} else {
console.log('No results returned.');
return null;
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
});
return ae_promises.load__exhibit_obj;
}
// Updated 2024-03-06
export async function handle_load_ae_obj_li__exhibit(
{
api_cfg,
event_id,
params={},
try_cache=true,
log_lvl=0
}: {
api_cfg: any,
event_id: any,
params: any,
try_cache?: boolean
log_lvl?: number
}
) {
console.log(`*** handle_load_ae_obj_li__exhibit() *** event_id=${event_id}`);
let enabled: string = (params.qry__enabled ?? 'enabled'); // all, disabled, enabled
let hidden: string = (params.qry__hidden ?? 'not_hidden'); // all, hidden, not_hidden
let limit: number = (params.qry__limit ?? 99); // 99
let offset: number = (params.qry__offset ?? 0); // 0
let params_json: key_val = {};
// params_json['and_qry'] = {};
// params_json['and_qry']['license_max'] = 10;
params_json['and_in_li'] = {
license_max : [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
};
// if (fulltext_search_qry_str && fulltext_search_qry_str.length > 2) {
// params_json['ft_qry'] = {
// 'default_qry_str': fulltext_search_qry_str,
// // 'location_address_json_ext': fulltext_search_qry_str, // JSON extracted text DB field
// // 'contact_li_json_ext': fulltext_search_qry_str, // JSON extracted text DB field
// };
// }
// console.log('params_json:', params_json);
// console.log(params_json);
// $events_sess.exhibits.status_qry__search = 'loading';
ae_promises.load__event_exhibit_obj_li = await api.get_ae_obj_li_for_obj_id_crud({
api_cfg: api_cfg,
obj_type: 'event_exhibit',
for_obj_type: 'event',
for_obj_id: event_id,
use_alt_table: false, // NOTE: This will use the table_name_alt value instead of the table_name value in the API config.
use_alt_base: false, // NOTE: This will use the base_name_alt value instead of the base_name value in the API config.
enabled: enabled,
hidden: hidden,
order_by_li: {'priority': 'DESC', 'sort': 'DESC', 'updated_on': 'DESC', 'created_on': 'DESC'},
// order_by_li: {'priority': 'DESC', 'sort': 'DESC', 'created_on': 'DESC', 'updated_on': 'DESC'},
limit: limit,
offset: offset,
params_json: params_json,
params: params,
log_lvl: log_lvl
})
.then(function (exhibit_obj_li_get_result) {
// console.log('Badge list:', exhibit_obj_li_get_result);
if (exhibit_obj_li_get_result) {
// $slct.exhibit_obj_li = exhibit_obj_li_get_result;
handle_db_save_ae_obj_li__exhibitor({obj_type: 'event_exhibit', obj_li: exhibit_obj_li_get_result});
return exhibit_obj_li_get_result;
} else {
// $slct.exhibit_obj_li = [];
return [];
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
})
.finally(function () {
// $events_sess.exhibits.status_qry__search = 'done';
// console.log('Badge list:', exhibit_obj_li_get_result);
// return exhibit_obj_li_get_result;
});
if (log_lvl) {
console.log('ae_promises.load__event_exhibit_obj_li:', ae_promises.load__event_exhibit_obj_li);
}
return ae_promises.load__event_exhibit_obj_li;
}
export async function handle_load_ae_obj_id__exhibit_tracking(
{
api_cfg,
exhibit_tracking_id,
try_cache=false,
log_lvl=0
}: {
api_cfg: any,
exhibit_tracking_id: string,
try_cache?: boolean,
log_lvl?: number
}
) {
console.log(`*** handle_load_ae_obj_id__exhibit_tracking() *** exhibit_tracking_id=${exhibit_tracking_id}`);
let params = {};
// $events_sess.exhibits.status_load__exhibit_tracking_obj = 'loading';
ae_promises.load__event_exhibit_tracking_obj = await api.get_ae_obj_id_crud({
api_cfg: api_cfg,
obj_type: 'event_exhibit_tracking',
obj_id: exhibit_tracking_id, // NOTE: This is the FQDN, not normally the ID.
use_alt_table: false, // NOTE: This will use the table_name_alt value instead of the table_name value in the API config.
use_alt_base: false, // NOTE: This will use the base_name_alt value instead of the base_name value in the API config.
params: params,
log_lvl: log_lvl
})
.then(function (exhibit_tracking_obj_get_result) {
if (exhibit_tracking_obj_get_result) {
// This is expecting a list
handle_db_save_ae_obj_li__exhibitor_tracking({obj_type: 'event_exhibit_tracking', obj_li: [exhibit_tracking_obj_get_result]});
return exhibit_tracking_obj_get_result;
} else {
console.log('No results returned.');
return null;
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
});
return ae_promises.load__event_exhibit_tracking_obj;
}
// Updated 2024-03-19
export async function handle_load_ae_obj_li__exhibit_tracking(
{
api_cfg,
exhibit_id,
params={},
try_cache=true,
log_lvl=0
}: {
api_cfg: any,
exhibit_id: any,
params: any,
try_cache?: boolean,
log_lvl?: number
}
) {
console.log(`*** handle_load_ae_obj_li__exhibit_tracking() *** exhibit_id=${exhibit_id}`);
let enabled: string = (params.qry__enabled ?? 'enabled'); // all, disabled, enabled
let hidden: string = (params.qry__hidden ?? 'all'); // all, hidden, not_hidden
let limit: number = (params.qry__limit ?? 99); // 99
let offset: number = (params.qry__offset ?? 0); // 0
let params_json: key_val = {};
ae_promises.load__event_exhibit_tracking_obj_li = await api.get_ae_obj_li_for_obj_id_crud({
api_cfg: api_cfg,
obj_type: 'event_exhibit_tracking',
for_obj_type: 'event_exhibit',
for_obj_id: exhibit_id,
use_alt_table: false, // NOTE: This will use the table_name_alt value instead of the table_name value in the API config.
use_alt_base: false, // NOTE: This will use the base_name_alt value instead of the base_name value in the API config.
enabled: enabled,
hidden: hidden,
order_by_li: {'priority': 'DESC', 'sort': 'DESC', 'updated_on': 'DESC', 'created_on': 'DESC'},
limit: limit,
offset: offset,
params_json: params_json,
params: params,
log_lvl: log_lvl
})
.then(function (exhibit_tracking_obj_li_get_result) {
// console.log('Exhibit tracking list:', exhibit_tracking_obj_li_get_result);
if (exhibit_tracking_obj_li_get_result) {
// $slct.exhibit_tracking_obj_li = exhibit_tracking_obj_li_get_result;
handle_db_save_ae_obj_li__exhibitor_tracking({obj_type: 'event_exhibit_tracking', obj_li: exhibit_tracking_obj_li_get_result});
return exhibit_tracking_obj_li_get_result;
} else {
// $slct.exhibit_tracking_obj_li = [];
return [];
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
})
.finally(function () {
// console.log('Exhibit tracking list:', exhibit_tracking_obj_li_get_result);
// return exhibit_tracking_obj_li_get_result;
});
if (log_lvl) {
console.log('ae_promises.load__event_exhibit_tracking_obj_li:', ae_promises.load__event_exhibit_tracking_obj_li);
}
return ae_promises.load__event_exhibit_tracking_obj_li;
}
// Updated 2024-03-22
export async function handle_create_ae_obj__exhibit_tracking(
{
api_cfg,
exhibit_id,
event_badge_id,
external_person_id,
params={},
log_lvl=0
}: {
api_cfg: any,
exhibit_id: string,
event_badge_id: string,
external_person_id: string,
params: key_val,
log_lvl: number
}
) {
console.log(`*** handle_create_ae_obj__exhibit_tracking() *** exhibit_id=${exhibit_id}, event_badge_id=${event_badge_id}`);
let params_json: key_val = {};
// $events_sess.exhibits.status_create__exhibit_tracking = 'loading';
ae_promises.create__event_exhibit_tracking = await api.create_ae_obj_crud({
api_cfg: api_cfg,
obj_type: 'event_exhibit_tracking',
fields: {
event_exhibit_id_random: exhibit_id,
event_badge_id_random: event_badge_id,
external_person_id: external_person_id,
},
key: api_cfg.api_crud_super_key,
params: params,
return_obj: true,
log_lvl: log_lvl
})
.then(function (exhibit_tracking_obj_create_result) {
// console.log('Exhibit tracking create:', exhibit_tracking_obj_create_result);
if (exhibit_tracking_obj_create_result) {
// $slct.exhibit_tracking_obj = exhibit_tracking_obj_create_result;
handle_db_save_ae_obj_li__exhibitor_tracking({obj_type: 'event_exhibit_tracking', obj_li: [exhibit_tracking_obj_create_result]});
return exhibit_tracking_obj_create_result;
} else {
// $slct.exhibit_tracking_obj = [];
return null;
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
})
.finally(function () {
// console.log('Exhibit tracking create:', exhibit_tracking_obj_create_result);
// return exhibit_tracking_obj_create_result;
});
if (log_lvl) {
console.log('ae_promises.create__event_exhibit_tracking:', ae_promises.create__event_exhibit_tracking);
}
return ae_promises.create__event_exhibit_tracking;
}
// Updated 2024-03-28
export async function handle_update_ae_obj__exhibit_tracking(
{
api_cfg,
exhibit_tracking_id,
data,
params={},
log_lvl=0
}: {
api_cfg: any,
exhibit_tracking_id: string,
data: any,
params: key_val,
log_lvl: number
}
) {
console.log(`*** handle_update_ae_obj__exhibit_tracking() *** exhibit_tracking_id=${exhibit_tracking_id}`);
ae_promises.update__event_exhibit_tracking = await api.update_ae_obj_id_crud({
api_cfg: api_cfg,
obj_type: 'event_exhibit_tracking',
obj_id: exhibit_tracking_id,
fields: data,
key: api_cfg.api_crud_super_key,
params: params,
return_obj: true,
log_lvl: log_lvl
})
.then(function (exhibit_tracking_obj_update_result) {
if (exhibit_tracking_obj_update_result) {
handle_db_save_ae_obj_li__exhibitor_tracking({obj_type: 'event_exhibit_tracking', obj_li: [exhibit_tracking_obj_update_result]});
return exhibit_tracking_obj_update_result;
} else {
return null;
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
})
.finally(function () {
});
if (log_lvl) {
console.log('ae_promises.update__event_exhibit_tracking:', ae_promises.update__event_exhibit_tracking);
}
return ae_promises.update__event_exhibit_tracking;
}
export async function handle_download_export__event_exhibit_tracking(
{
api_cfg,
exhibit_id,
file_type='CSV', // 'CSV' or 'Excel'
return_file=true,
filename='no_filename.csv',
auto_download=false,
params={},
log_lvl=0
}: {
api_cfg: any,
exhibit_id: string,
file_type?: string,
return_file?: boolean,
filename?: string,
auto_download?: boolean,
params?: key_val,
log_lvl?: number
}
) {
console.log('*** ae_events_functions.js: get_event_exhibit_tracking_export() ***');
const endpoint = `/event/exhibit/${exhibit_id}/tracking/export`;
if (file_type == 'CSV' || file_type == 'Excel') {
params['file_type'] = file_type;
}
params['return_file'] = true;
ae_promises.download__event_exhibit_tracking_export_file = await api.get_object({
api_cfg: api_cfg,
endpoint: endpoint,
params: params,
return_blob: true,
filename: filename,
auto_download: auto_download,
log_lvl: log_lvl
});
if (log_lvl) {
console.log('ae_promises.download__event_exhibit_tracking_export_file:', ae_promises.download__event_exhibit_tracking_export_file);
}
return ae_promises.download__event_exhibit_tracking_export_file;
}
// This function will loop through the event_exhibit_obj_li and save each one to the DB.
export function handle_db_save_ae_obj_li__exhibitor(
{
obj_type,
obj_li=[],
log_lvl=0
}: {
obj_type: string,
obj_li: any[],
log_lvl?: number
}
) {
if (log_lvl) {
console.log(`*** handle_db_save_ae_obj_li__exhibitor() ***`);
}
if (obj_li && obj_li.length) {
obj_li.forEach(async function (obj) {
if (log_lvl) {
console.log(`ae_obj ${obj_type}:`, obj);
}
try {
const id_random = await db_events.exhibits.put({
id_random: obj.event_exhibit_id_random,
event_exhibit_id_random: obj.event_exhibit_id_random,
event_id_random: obj.event_id_random,
code: obj.code,
name: obj.name,
description: obj.description,
staff_passcode: obj.staff_passcode,
data_json: obj.data_json,
leads_api_access: obj.leads_api_access,
leads_custom_questions_json: obj.leads_custom_questions_json,
leads_device_sm_qty: obj.leads_device_sm_qty,
leads_device_lg_qty: obj.leads_device_lg_qty,
license_max: obj.license_max,
license_li_json: obj.license_li_json,
cfg_json: obj.cfg_json,
enable: obj.enable,
hide: obj.hide,
priority: obj.priority,
sort: obj.sort,
group: obj.group,
notes: obj.notes,
created_on: obj.created_on,
updated_on: obj.updated_on,
});
// console.log(`Put obj with ID: ${obj.event_exhibit_id_random} or ${id_random}`);
} catch (error) {
let status = `Failed to put ${obj.event_exhibit_id_random}: ${error}`;
console.log(status);
}
// const id_random = await db_events.exhibits.put(obj);
// console.log(`Put obj with ID: ${obj.event_exhibit_id_random}`);
});
return true;
}
}
// This function will loop through the event_exhibit_tracking_obj_li and save each one to the DB.
export function handle_db_save_ae_obj_li__exhibitor_tracking(
{
obj_type,
obj_li,
log_lvl=0
}: {
obj_type: string,
obj_li: any,
log_lvl?: number
}
) {
if (log_lvl) {
console.log(`*** handle_db_save_ae_obj_li__exhibitor_tracking() ***`);
}
if (obj_li && obj_li.length) {
obj_li.forEach(async function (obj: any) {
if (log_lvl) {
console.log(`ae_obj ${obj_type}:`, obj);
}
try {
const id_random = await db_events.exhibit_tracking.put({
id_random: obj.event_exhibit_tracking_id_random,
event_exhibit_tracking_id_random: obj.event_exhibit_tracking_id_random,
event_exhibit_id_random: obj.event_exhibit_id_random,
event_badge_id_random: obj.event_badge_id_random,
event_person_id_random: obj.event_person_id_random,
external_person_id: obj.external_person_id,
exhibitor_notes: obj.exhibitor_notes,
responses_json: obj.responses_json,
data_json: obj.data_json,
event_exhibit_name: obj.event_exhibit_name,
event_badge_title_names: obj.event_badge_title_names,
event_badge_given_name: obj.event_badge_given_name,
event_badge_family_name: obj.event_badge_family_name,
event_badge_designations: obj.event_badge_designations,
event_badge_full_name: obj.event_badge_full_name,
event_badge_full_name_override: obj.event_badge_full_name_override,
event_badge_professional_title: obj.event_badge_professional_title,
event_badge_professional_title_override: obj.event_badge_professional_title_override,
event_badge_affiliations: obj.event_badge_affiliations,
event_badge_affiliations_override: obj.event_badge_affiliations_override,
event_badge_email: obj.event_badge_email,
event_badge_email_override: obj.event_badge_email_override,
event_badge_location: obj.event_badge_location,
event_badge_location_override: obj.event_badge_location_override,
event_badge_country: obj.event_badge_country,
enable: obj.enable,
hide: obj.hide,
priority: obj.priority,
sort: obj.sort,
group: obj.group,
notes: obj.notes,
created_on: obj.created_on,
updated_on: obj.updated_on,
});
// console.log(`Put obj with ID: ${obj.event_exhibit_tracking_id_random} or ${id_random}`);
} catch (error) {
let status = `Failed to put ${obj.event_exhibit_tracking_id_random}: ${error}`;
console.log(status);
}
// const id_random = await db_events.exhibit_tracking.put(obj);
// console.log(`Put obj with ID: ${obj.event_exhibit_tracking_id_random}`);
});
return true;
}
}

View File

@@ -0,0 +1,135 @@
// This file is used to export all the functions that are used for Aether Events related functions.
// Import all the functions from this library:
import * as events from "$lib/ae_events__event";
import {
load_ae_obj_id__event_file,
load_ae_obj_li__event_file,
delete_ae_obj_id__event_file,
create_event_file_obj_from_hosted_file_async,
update_ae_obj__event_file,
search__event_file,
db_save_ae_obj_li__event_file,
} from "$lib/ae_events__event_file";
import {
handle_load_ae_obj_id__exhibit,
handle_load_ae_obj_li__exhibit,
handle_load_ae_obj_id__exhibit_tracking,
handle_load_ae_obj_li__exhibit_tracking,
handle_create_ae_obj__exhibit_tracking,
handle_update_ae_obj__exhibit_tracking,
handle_download_export__event_exhibit_tracking,
handle_db_save_ae_obj_li__exhibitor,
} from "$lib/ae_events__exhibit";
import {
load_ae_obj_id__event_location,
load_ae_obj_li__event_location,
create_ae_obj__event_location,
update_ae_obj__event_location,
db_save_ae_obj_li__event_location,
} from "$lib/ae_events__event_location";
import {
load_ae_obj_id__event_session,
load_ae_obj_li__event_session,
create_ae_obj__event_session,
update_ae_obj__event_session,
qry__event_session,
search__event_session,
db_save_ae_obj_li__event_session,
email_sign_in__event_session,
} from "$lib/ae_events__event_session";
import {
load_ae_obj_id__event_presentation,
load_ae_obj_li__event_presentation,
create_ae_obj__event_presentation,
update_ae_obj__event_presentation,
db_save_ae_obj_li__event_presentation,
} from "$lib/ae_events__event_presentation";
import {
load_ae_obj_id__event_presenter,
load_ae_obj_li__event_presenter,
delete_ae_obj_id__event_presenter,
create_ae_obj__event_presenter,
update_ae_obj__event_presenter,
search__event_presenter,
db_save_ae_obj_li__event_presenter,
email_sign_in__event_presenter,
} from "$lib/ae_events__event_presenter";
import {
handle_load_ae_obj_id__badge,
handle_load_ae_obj_li__badge,
handle_search__event_badge,
handle_db_save_ae_obj_li__badge,
} from "$lib/ae_events__event_badge";
let export_obj = {
load_ae_obj_id__event: events.load_ae_obj_id__event,
load_ae_obj_li__event: events.load_ae_obj_li__event,
qry_ae_obj_li__event: events.qry_ae_obj_li__event,
create_ae_obj__event: events.create_ae_obj__event,
update_ae_obj__event: events.update_ae_obj__event,
db_save_ae_obj_li__event: events.db_save_ae_obj_li__event,
sync_config__event_pres_mgmt: events.sync_config__event_pres_mgmt,
load_ae_obj_id__event_file: load_ae_obj_id__event_file,
load_ae_obj_li__event_file: load_ae_obj_li__event_file,
delete_ae_obj_id__event_file: delete_ae_obj_id__event_file,
update_ae_obj__event_file: update_ae_obj__event_file,
search__event_file: search__event_file,
db_save_ae_obj_li__event_file: db_save_ae_obj_li__event_file,
load_ae_obj_id__event_location: load_ae_obj_id__event_location,
load_ae_obj_li__event_location: load_ae_obj_li__event_location,
create_ae_obj__event_location: create_ae_obj__event_location,
update_ae_obj__event_location: update_ae_obj__event_location,
db_save_ae_obj_li__event_location: db_save_ae_obj_li__event_location,
load_ae_obj_id__event_session: load_ae_obj_id__event_session,
load_ae_obj_li__event_session: load_ae_obj_li__event_session,
create_ae_obj__event_session: create_ae_obj__event_session,
update_ae_obj__event_session: update_ae_obj__event_session,
qry__event_session: qry__event_session,
search__event_session: search__event_session,
email_sign_in__event_session: email_sign_in__event_session,
db_save_ae_obj_li__event_session: db_save_ae_obj_li__event_session,
load_ae_obj_id__event_presentation: load_ae_obj_id__event_presentation,
load_ae_obj_li__event_presentation: load_ae_obj_li__event_presentation,
create_ae_obj__event_presentation: create_ae_obj__event_presentation,
update_ae_obj__event_presentation: update_ae_obj__event_presentation,
db_save_ae_obj_li__event_presentation: db_save_ae_obj_li__event_presentation,
load_ae_obj_id__event_presenter: load_ae_obj_id__event_presenter,
load_ae_obj_li__event_presenter: load_ae_obj_li__event_presenter,
delete_ae_obj_id__event_presenter: delete_ae_obj_id__event_presenter,
create_ae_obj__event_presenter: create_ae_obj__event_presenter,
update_ae_obj__event_presenter: update_ae_obj__event_presenter,
search__event_presenter: search__event_presenter,
db_save_ae_obj_li__event_presenter: db_save_ae_obj_li__event_presenter,
email_sign_in__event_presenter: email_sign_in__event_presenter,
handle_load_ae_obj_id__badge: handle_load_ae_obj_id__badge,
handle_load_ae_obj_li__badge: handle_load_ae_obj_li__badge,
handle_search__event_badge: handle_search__event_badge,
handle_db_save_ae_obj_li__badge: handle_db_save_ae_obj_li__badge,
handle_load_ae_obj_id__exhibit: handle_load_ae_obj_id__exhibit,
handle_load_ae_obj_li__exhibit: handle_load_ae_obj_li__exhibit,
handle_load_ae_obj_id__exhibit_tracking: handle_load_ae_obj_id__exhibit_tracking,
handle_load_ae_obj_li__exhibit_tracking: handle_load_ae_obj_li__exhibit_tracking,
handle_create_ae_obj__exhibit_tracking: handle_create_ae_obj__exhibit_tracking,
handle_update_ae_obj__exhibit_tracking: handle_update_ae_obj__exhibit_tracking,
handle_download_export__event_exhibit_tracking: handle_download_export__event_exhibit_tracking,
handle_db_save_ae_obj_li__exhibitor: handle_db_save_ae_obj_li__exhibitor,
create_event_file_obj_from_hosted_file_async: create_event_file_obj_from_hosted_file_async,
};
export let events_func = export_obj;

588
src/lib/ae_events_stores.ts Normal file
View File

@@ -0,0 +1,588 @@
import { localStorageStore } from '@skeletonlabs/skeleton';
import { writable } from 'svelte/store';
import type { Writable } from 'svelte/store';
import type { key_val } from '$lib/ae_stores';
// Set the version for the app data. Changing this should force a notification and ask the user to clear and reload the page.
let ver = '2024-08-21_1646';
let ver_idb = '2024-08-21_1645';
/* *** BEGIN *** Initialize events_local_data_struct */
// Longer-term app data. This should be stored to *local* storage.
// Updated 2024-03-06
let events_local_data_struct: key_val = {
ver: ver,
ver_idb: ver_idb,
// Shared
name: 'Aether - Events (SvelteKit 2.x Svelte 4.x)',
title: `OSIT's Æ Events`, // - Dev SvelteKit`, // &AElig;
'ds': {},
'events_cfg_json': {},
'event_id': null,
// all, disabled, enabled
'qry__enabled': 'enabled',
// all, hidden, not_hidden
'qry__hidden': 'not_hidden',
'qry__limit': 20,
'qry__offset': 0,
// The show details is intended for things like meta data and additional details that are not always needed.
show_details: false,
auth__person: {}, // allow, id, name, email, passcode, etc
// The auth__entered_key (usually email or person_id) and auth__entered_passcode is found under events_sess.entered_key and events_sess.entered_passcode because it should be temporary.
// auth__entered_passcode: null,
// The auth__kv (key value pairs) is used to store the xyz IDs that the browser client can access. This is a key value list of xyz ID and created datetime stamp (or just true). These should not be more than X days old.
auth__kv: {
event: {
// 'LNDF-67-89-92': true
},
exhibit: {
// 'LNDF-67-89-92': true
},
location: {
// 'LNDF-67-89-92': true
},
session: {
// 'LNDF-67-89-92': true, false, 'read', 'write'
},
presentation: {
// 'LNDF-67-89-92': true
},
presenter: {
// 'LNDF-67-89-92': true
},
person: {
// 'LNDF-67-89-92': true
},
},
// auth__session_kv: {
// // {'LNDF-67-89-92': true}
// },
// auth__presentation_kv: {
// // {'LNDF-67-89-92': true}
// },
// auth__presenter_kv: {
// // {'LNDF-67-89-92': true}
// },
// Badge Printing
'badges': {
auto_view: true,
show_hidden: false, // These are hidden (archived) leads so the list is not as long.
show_not_enabled: false,
show_printed: false,
allow_reprint: false,
'show_element__cfg': true,
'show_element__cfg_detail': false,
'show_element__access_type': true,
'theme_mode': 'dark',
'theme_name': 'wintry',
'classes__form': 'border border-surface-200 p-4 space-y-4 rounded-container-token',
},
// Event Files - uploads for sessions, presenters, etc
// 'files': {
// },
// Event Presentation Launcher (and native Electron app)
'launcher': {
// default - browser, onsite - browser onsite, native - Electron app onsite
app_mode: 'default', // 'default', 'native', 'onsite'
ws_connect: false,
qry_limit__sessions: 50,
qry_limit__presentations: 25,
qry_limit__presenters: 75,
qry_limit__files: 75,
show_content__disabled_files: false,
show_content__hidden_files: false,
show_content__hidden_presentations: false,
show_content__hidden_presenters: false,
show_content__hidden_sessions: false,
// These should be renamed to match the pres_mgmt section. Use "hide" instead of "show".
show_content__session_code: true,
show_content__presentation_code: true,
show_content__presenter_code: true,
show_section__controller: false,
datetime_format: 'datetime_12_long',
time_format: 'time_12_short',
time_hours: 12, // 12 or 24
slct: {
event_id: null,
event_location_id: null,
event_session_id: null,
event_presentation_id: null,
event_presenter_id: null,
event_file_id: null, // event_file_id
},
native: {
// 'local_file_cache_path': aether_cfg_data.app.local_file_cache_path,
// 'host_file_temp_path': aether_cfg_data.app.host_file_temp_path,
'host_file_config_path': 'device_configs/ae_native_app_config.default.json',
},
screen_saver_img_list: [],
modal__title: '-- Not Set --',
modal__open: null,
modal__open_filename: null,
modal_img_src: null,
controller: 'local',
controller_group_code: 'launcher-00',
// controller_cmd: null,
// controller_trigger_send: null,
},
// Lead Retrievals (Exhibit)
'leads': {
show_option__paid_tab: true,
show_content__scan_alert: true, // For QR scanner bug...
show_content__scan_requirements: true,
show_content__custom_question_descriptions: true,
show_content__email_link_warning: true,
default_to_scan: true,
// For ISHLT 2024 Annual Meeting only!
default__external_registration_id: '2024_Annual Meeting',
auto_view: true, // Show the new lead after added by scan or search
auto_hide_on_sign_in: true,
show_hidden: false, // These are hidden (archived) leads so the list is not as long.
show_not_enabled: false,
refresh_interval__tracking_li: 30000, // 30 seconds
// The entered_passcode is the exhibit booths shared passcode for staff. This is used to initially access the lead retrieval service.
entered_passcode: null,
// The auth_exhibit_kv (key value pairs) is used to store the exhibit IDs that the browser client can access. This is a key value list of exhibit ID and created datetime stamp. These should not be more than X days old. The entered_passcode for events_sess.leads is what they are entering to log in.
auth_exhibit_kv: {
// {'LNDF-67-89-92': {key: 'example@oneskyit.com', updated_on: '2024-03-13T08:05:29Z}}
},
// The auth_exhibit_license_li is used to store the exhibit license(s) being used on the browser client. There can be multiple exhibit IDs, but only one license per exhibit ID for the browser client. This is used to determine who can actually access and use the lead retrieval service. This is a key value list of key (email address) and created datetime stamp. These should not be more than X days old.
// auth_exhibit_license_li: {
// // 'LNDF-67-89-92': { 'key': 'example@oneskyit.com', 'updated_on': '2024-03-13T08:05:29Z'}
// },
edit_license_li: false,
// The "tab" is a key value list of exhibit ID and tab name. This is intentionally using local storage to store the current tab for each exhibit.
// example: {'LNDF-67-89-92': 'start', 'OFLN-32-38-14': 'add_scan'}
tab: {},
},
// Presentation Management
pres_mgmt: {
sync_local_config: false,
lock_config: false,
datetime_format: 'datetime_12_long',
time_format: 'time_12_short',
time_hours: 12, // 12 or 24
qry_enabled: 'enabled', // all, disabled, enabled
qry_hidden: 'not_hidden', // all, hidden, not_hidden
qry_limit__files: 75,
qry_limit__presentations: 25,
qry_limit__presenters: 75,
qry_limit__sessions: 100,
qry_max: 500, // This is the max number the limit is allowed to be set to.
qry_and__file_count: true, // Essentially it should be greater than 0
save_search_text: true,
saved_search__session: null,
// show_content__agree_text: false,
show_content__event_view: null,
show__launcher_link: false,
show__location_link: false,
show_content__location_qr: false,
show_content__presentation_description: false, // Note that this is for *all* presentations in the user interface. It is a global setting.
show_content__presenter_page_help: true,
// show_content__presenter_start: false,
show_content__presenter_view: null,
show_content__presenter_qr: false,
show_content__session_description: false,
show_content__session_files: false,
show_content__session_help: true,
show_content__session_presentations: false,
show_content__session_search_view: null,
show_content__session_search_help: true,
show_content__session_search_room_name: false,
show_content__session_view: null,
show_content__session_qr: false,
hide__session_msg: true,
hide__session_poc: true,
show_content__disabled_files: false,
show_content__hidden_files: false,
show_content__hidden_presentations: false,
show_content__hidden_presenters: false,
show_content__hidden_sessions: false,
// No longer used. Use "hide" instead of "show". Now it is initially set in the remote event config sync.
// show_content__presentation_code: true,
// show_content__presenter_code: true,
// show_content__session_code: true,
show_menu__presenter: null,
show_menu__session: null,
show_menu__session_search: null,
show_menu__event_reports: null,
show_report__presenters_agree: false,
show_report__recent_files: false,
// time_format: 'time_12_short', // 'time_short', 'time_12_short'
disable_submit__opt_out: true,
submit_status__opt_out: null,
},
// Speakers Management (Collection)
// 'speakers': {
// },
// other
}
// console.log(`AE Stores - App Events Local Storage Data:`, events_local_data_struct);
// This works, but does not uses local storage:
// export let ae_loc = writable(events_local_data_struct);
// This works and uses *local* storage:
export let events_loc: Writable<key_val> = localStorageStore('ae_events_loc', events_local_data_struct);
// console.log(`AE Stores - App Local Storage Data:`, get(ae_loc));
/* *** BEGIN *** Initialize events_session_data_struct */
// Temporary app data. This should be stored to session storage.
// Updated 2024-03-06
let events_session_data_struct: key_val = {
ver: ver,
ver_idb: ver_idb,
log_lvl: 1,
// Shared
'ds': {
'submit_status': null,
},
'ds_loaded': {
},
'qry__enabled': 'enabled', // all, disabled, enabled
'qry__hidden': 'not_hidden', // all, hidden, not_hidden
'qry__limit': 20,
'qry__offset': 0,
// This is intended to only be temporary.
auth__person: {},
auth__entered_key: null,
auth__entered_passcode: null,
auth__kv: {
event: {},
exhibit: {},
location: {},
session: {},
presentation: {},
presenter: {},
person: {},
},
// Badge Printing
'badges': {
'fulltext_search_qry_str': null,
'status_qry__search': null,
show_form__search: true,
show_form__search_results: true,
show_form__scan: false,
qr_scan_start: true,
qr_scan_result: null,
},
// Event Files - uploads for sessions, presenters, etc
'files': {
disable_submit__event_file_obj: null,
status__submit: null,
status__file_list: null, // processing, complete
processed_file_list: [],
},
// Event Presentation Launcher (and native Electron app)
'launcher': {
ws_connect_status: null,
av_recording_status: null,
controller_cmd: null,
controller_trigger_send: null,
event_file_open: {}, // This is from the older Launcher.
native: {
},
},
// Lead Retrievals (Exhibit)
'leads': {
example: true,
show_form__license: false,
show_form__search: false,
show_form__scan: false,
show_form__view_lead: false, // Set to event_exhibit_tracking_id
// show_form__view_lead: [],
show_confirm__add_lead: [],
submit_status__license: null, // 'saving', 'created', 'updated'
// create_status__license: null, // 'creating', 'created', 'updated'
// update_status__license: null, // 'updating', 'created', 'updated'
submit_status__search: null, // 'searching', 'complete'
// The entered_passcode is the exhibit booths shared passcode for staff. This is used to initially access the lead retrieval service.
entered_passcode: null,
tmp_license: {
'index': null,
// 'agree' : false, // The user must agree to the license agreement.
'email': '',
'full_name': '',
'passcode': '',
'session_count': 0,
'updated_on': new Date().toISOString()
},
entered_search_str: null,
lead_data_changed: null,
qr_scan_start: true,
qr_scan_result: null,
},
'stripe': {
'license_qty': 1,
'rental_qty': 0,
'rental_option': true,
'api_use': false,
'client_reference_id': null,
'publishable_key': 'pk_live_zqaWNDfak2eDHeqnRiyaJcFi',
'btn_payment_id': null,
'btn_1_license': 'buy_btn_1OvqWJ2gJkNsDuiNqMCWz5nG',
'btn_1_license_rental': 'buy_btn_1OvqVA2gJkNsDuiNhk9r8Io2',
'btn_3_license': 'buy_btn_1OvrI22gJkNsDuiNXjBg3c4Y',
'btn_3_license_rental': 'buy_btn_1OvrKa2gJkNsDuiNhSBCkNau',
'btn_6_license': 'buy_btn_1OvrWc2gJkNsDuiN7mnwvZNL',
'btn_6_license_rental': 'buy_btn_1OvrXP2gJkNsDuiNZpWZs3Uy',
'btn_10_license': 'buy_btn_1OvrPM2gJkNsDuiNRCMHfSuz',
'btn_10_license_rental': 'buy_btn_1OvrPs2gJkNsDuiN1nPkjPOM',
},
// Presentation Management
pres_mgmt: {
// link: {
// ae_core: true,
// pres_mgmt__launcher_id: null, // event_location_id
// pres_mgmt__location_id: null, // event_location_id
// pres_mgmt__presenter_id: null, // event_presenter_id
// pres_mgmt__reports: null, // event_id
// pres_mgmt__session_id: null, // event_session_id
// pres_mgmt__session_search: null, // event_id
// },
// presenter__url_str: null,
presenter__updated_on: null,
session_updated_on: null,
location_name_qry_str: null,
fulltext_search_qry_str: null,
status_qry__search: null,
disable_submit__event_file_obj: true,
show_form__search: true,
show_form__search_results: true,
show_content__agree_text: false,
show_content__presenter_start: false,
show_content__presentation_description: false, // Note that this is per presentation. The event_presentation_id_random should match.
show_report__presenters_agree: false,
show_report__recent_files: false,
show_field_edit__filename: false, // For file rename
new_upload_list: null,
files_uploading_count: null,
qry_limit__sessions: 75,
qry_limit__presentations: 25,
qry_limit__presenters: 75,
qry_limit__files: 75,
show_fields__presentation: true,
show_fields__session: true,
status_rpt: {
recent_files: null,
presenters_agree: null,
presenters_biography: null,
},
tmp_val__filename_no_ext: null, // For file rename
},
// Speakers Management (Collection)
// other
};
// console.log(`AE Stores - App Events Session Storage Data:`, events_session_data_struct);
export let events_sess = writable(events_session_data_struct);
/* *** BEGIN *** Initialize events_slct and events_trigger */
/* The slct and slct_trigger variable should not be stored in local storage. Only use session storage because browser tabs can be open to different events, badges, exhibits, etc. */
// Intended for temporary session storage.
// Updated 2024-03-06
let events_slct_obj_template: key_val = {
// Top level
'event_id': null,
'event_obj': {},
'event_obj_li': [],
// Sub-level event_
'abstract_id': null,
'abstract_obj': {},
'abstract_obj_li': [],
'badge_id': null,
'badge_obj': {},
'badge_obj_li': [],
'badge_template_id': null,
'badge_template_obj': {},
'badge_template_obj_li': [],
'device_id': null,
'device_obj': {},
'device_obj_li': [],
'exhibit_id': null,
'exhibit_obj': {},
'exhibit_obj_li': [],
// Rename these to badge_tracking_*?
'exhibit_tracking_id': null,
'exhibit_tracking_obj': {},
'exhibit_tracking_obj_li': [],
'file_id': null,
'file_obj': {},
'file_obj_li': [],
'event_file_obj': {},
'event_file_obj_li': [],
'location_id': null,
'location_obj': {},
'location_obj_li': [],
'person_id': null,
'person_obj': {},
'person_obj_li': [],
'presentation_id': null,
'presentation_obj': {},
'presentation_obj_li': [],
'event_presentation_obj': {},
'presenter_id': null,
'presenter_obj': {},
'presenter_obj_li': [],
'event_presenter_obj': {},
'session_id': null,
'session_obj': {},
'session_obj_li': [],
'event_session_obj': {},
'lq__presenter_obj': {}, // Testing passing a LiveQuery object around...
'auth__event_presenter_id': null,
'auth__event_presentation_id': null,
};
// console.log(`AE Stores - Selected Events Objects:`, events_slct_obj_template);
// This works, and uses *session* (not local) storage:
export let events_slct = writable(events_slct_obj_template);
// This works and uses *local* storage:
// export let events_slct: Writable<key_val> = localStorageStore('ae_events_slct', events_slct_obj_template);
/* *** BEGIN *** Initialize events_trigger */
// Intended for temporary session storage.
// Updated 2024-03-06
export let events_trigger: any = writable(null);
// console.log(`AE Events Stores - Events Trigger:`, events_trigger);
let tmp__events_trig: key_val = {
'event_id': null,
'event_id_li': [],
'event_location_id': null,
'event_location_id_li': [],
'event_session_id': null,
'event_session_id_li': [],
'event_presentation_id': null,
'event_presentation_id_li': [],
'event_presenter_id': null,
'event_presenter_id_li': [],
};
// console.log(`AE Stores - Events Trigger:`, events_trig);
export let events_trig: Writable<key_val> = writable(tmp__events_trig);
/* *** BEGIN *** TESTING Initialize trig_resp */
// The idea behind this is for a shared (Svelte app (within Events for now)) trigger and response. In theory this could be used to monitor multiple downloads or have a universal status area. Intended for temporary session storage.
// Updated 2024-06-25
let tmp__events_trig_kv: key_val = {};
// {
// 'example-1':
// {
// 'a-rand-id-1': true,
// 'a-rand-id-2': false,
// 'a-rand-id-3': Promise.resolve('This is a test promise.'),
// },
// 'example-2':
// {
// 'a-rand-id-4': true,
// 'a-rand-id-5': false,
// 'a-rand-id-6': Promise.resolve('This is a test promise.'),
// },
// };
export let events_trig_kv = writable(tmp__events_trig_kv);

146
src/lib/ae_idaa_stores.ts Normal file
View File

@@ -0,0 +1,146 @@
import { localStorageStore } from '@skeletonlabs/skeleton';
import { writable } from 'svelte/store';
import type { Writable } from 'svelte/store';
import type { key_val } from '$lib/ae_stores';
import { offset } from '@floating-ui/dom';
// Set the version for the app data. Changing this should force a notification and ask the user to clear and reload the page.
let ver = '2024-08-21_1646';
let ver_idb = '2024-08-21_1645';
/* *** BEGIN *** Initialize idaa_local_data_struct */
// Longer-term app data. This should be stored to *local* storage.
// Updated 2024-03-06
let idaa_local_data_struct: key_val = {
ver: ver,
ver_idb: ver_idb,
// Shared
name: 'Aether - IDAA (SvelteKit 2.x Svelte 4.x)',
title: `OSIT's Æ IDAA`, // - Dev SvelteKit`, // &AElig;
novi_uuid: null,
novi_email: null,
novi_full_name: null,
novi_admin_li: [],
novi_trusted_li: [],
'ds': {},
'idaa_cfg_json': {},
// all, disabled, enabled
'qry__enabled': 'enabled',
// all, hidden, not_hidden
'qry__hidden': 'not_hidden',
'qry__limit': 20,
'qry__offset': 0,
archives: {
enabled: 'enabled', // all, disabled, enabled
hidden: 'not_hidden', // all, hidden, not_hidden
limit: 150,
offset: 0,
},
bb: {
enabled: 'enabled', // all, disabled, enabled
hidden: 'not_hidden', // all, hidden, not_hidden
limit: 150,
offset: 0,
show_list__post_obj_li: true,
},
recovery_meetings: {
qry__enabled: 'enabled', // all, disabled, enabled
qry__hidden: 'not_hidden', // all, hidden, not_hidden
qry__limit: 150,
qry__offset: 0,
qry__fulltext_str: null,
qry__physical: null,
qry__type: null,
qry__virtual: null,
},
};
// console.log(`AE Stores - App IDAA Local Storage Data:`, idaa_local_data_struct);
// This works, but does not uses local storage:
// export let ae_loc = writable(idaa_local_data_struct);
// This works and uses *local* storage:
export let idaa_loc: Writable<key_val> = localStorageStore('ae_idaa_loc', idaa_local_data_struct);
// console.log(`AE Stores - App Local Storage Data:`, get(ae_loc));
/* *** BEGIN *** Initialize idaa_session_data_struct */
// Temporary app data. This should be stored to session storage.
// Updated 2024-03-06
let idaa_session_data_struct: key_val = {
ver: ver,
ver_idb: ver_idb,
log_lvl: 1,
archives: {
qry__status: null,
},
bb: {
qry__status: null,
},
recovery_meetings: {
qry__status: null,
// qry__fulltext_str: null,
show__modal_edit: false,
show__modal_view: false,
},
};
// console.log(`AE Stores - App IDAA Session Storage Data:`, idaa_session_data_struct);
export let idaa_sess = writable(idaa_session_data_struct);
/* *** BEGIN *** Initialize idaa_slct and idaa_trigger */
/* The slct and slct_trigger variable should not be stored in local storage. Only use session storage because browser tabs can be open to different idaa, badges, exhibits, etc. */
// Intended for temporary session storage.
// Updated 2024-03-06
let idaa_slct_obj_template: key_val = {
// Top level
'event_id': null,
'event_obj': {},
'event_obj_li': [],
'archive_id': null,
'archive_obj': {},
'archive_obj_li': [],
'archive_content_id': null,
'archive_content_obj': {},
'archive_content_obj_li': [],
'post_id': null,
'post_obj': {},
'post_obj_li': [],
'post_comment_id': null,
'post_comment_obj': {},
'post_comment_obj_li': [],
};
// console.log(`AE Stores - Selected IDAA Objects:`, idaa_slct_obj_template);
// This works, and uses *session* (not local) storage:
export let idaa_slct = writable(idaa_slct_obj_template);
// This works and uses *local* storage:
// export let idaa_slct: Writable<key_val> = localStorageStore('ae_idaa_slct', idaa_slct_obj_template);
/* *** BEGIN *** Initialize idaa_trigger */
// Intended for temporary session storage.
// Updated 2024-03-06
export let idaa_trigger: any = writable(null);
// console.log(`AE IDAA Stores - IDAA Trigger:`, idaa_trigger);

646
src/lib/ae_notes__note.ts Normal file
View File

@@ -0,0 +1,646 @@
import type { key_val } from '$lib/ae_stores';
import { api } from '$lib/api';
import { db_notes } from "$lib/db_notes";
// import { load_ae_obj_li__note_other } from "$lib/ae_notes__note_other";
let ae_promises: key_val = {};
// Updated 2024-09-25
export async function load_ae_obj_id__note(
{
api_cfg,
note_id,
// inc_other_li = false,
try_cache = true,
log_lvl = 0
}: {
api_cfg: any,
note_id: string,
// inc_other_li?: boolean,
try_cache?: boolean,
log_lvl?: number
}
) {
console.log(`*** load_ae_obj_id__note() *** note_id=${note_id}`);
let params = {};
ae_promises.load__note_obj = await api.get_ae_obj_id_crud({
api_cfg: api_cfg,
obj_type: 'note',
obj_id: note_id, // NOTE: This is the FQDN, not normally the ID.
use_alt_table: true, // NOTE: This will use the table_name_alt value instead of the table_name value in the API config.
use_alt_base: false, // NOTE: This will use the base_name_alt value instead of the base_name value in the API config.
params: params,
log_lvl: log_lvl
})
.then(function (note_obj_get_result) {
if (note_obj_get_result) {
if (try_cache) {
// This is expecting a list
db_save_ae_obj_li__note({
obj_type: 'note',
obj_li: [note_obj_get_result]
});
}
return note_obj_get_result;
} else {
console.log('No results returned.');
return null;
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
});
if (log_lvl) {
console.log('ae_promises.load__note_obj:', ae_promises.load__note_obj);
}
// if (inc_other_li) {
// // Load the others for the note
// if (log_lvl) {
// console.log(`Need to load the other list for the note now`);
// }
// let load_note_other_obj_li = load_ae_obj_li__note_other({
// api_cfg: api_cfg,
// for_obj_type: 'note',
// for_obj_id: note_id,
// inc_other_li: inc_other_li,
// params: {qry__enabled: 'all', qry__limit: 25},
// try_cache: try_cache,
// log_lvl: log_lvl
// })
// .then((note_other_obj_li) => {
// if (log_lvl) {
// console.log(`note_other_obj_li = `, note_other_obj_li);
// }
// return note_other_obj_li;
// });
// if (log_lvl) {
// console.log(`note_other_obj_li = `, load_note_other_obj_li);
// }
// ae_promises.load__note_obj.note_other_li = load_note_other_obj_li;
// }
return ae_promises.load__note_obj;
}
// Updated 2024-09-25
export async function load_ae_obj_li__note(
{
api_cfg,
for_obj_type = 'account',
for_obj_id,
// inc_other_li = false,
order_by_li = {'priority': 'DESC', 'sort': 'DESC', 'name': 'ASC', 'updated_on': 'DESC', 'created_on': 'DESC'},
params = {},
try_cache = true,
log_lvl = 0
}: {
api_cfg: any,
for_obj_type: string,
for_obj_id: string,
// inc_other_li?: boolean,
order_by_li?: key_val,
params?: key_val,
try_cache?: boolean,
log_lvl?: number
}
) {
console.log(`*** load_ae_obj_li__note() *** for_obj_type=${for_obj_type} for_obj_id=${for_obj_id}`);
let enabled: string = (params.qry__enabled ?? 'enabled'); // all, disabled, enabled
let hidden: string = (params.qry__hidden ?? 'not_hidden'); // all, hidden, not_hidden
let limit: number = (params.qry__limit ?? 99); // 99
let offset: number = (params.qry__offset ?? 0); // 0
let params_json: key_val = {};
// console.log('params_json:', params_json);
ae_promises.load__note_obj_li = await api.get_ae_obj_li_for_obj_id_crud({
api_cfg: api_cfg,
obj_type: 'note',
for_obj_type: for_obj_type,
for_obj_id: for_obj_id,
use_alt_table: true, // NOTE: This will use the table_name_alt value instead of the table_name value in the API config.
use_alt_base: false, // NOTE: This will use the base_name_alt value instead of the base_name value
enabled: enabled,
hidden: hidden,
order_by_li: order_by_li,
limit: limit,
offset: offset,
params_json: params_json,
params: params,
log_lvl: log_lvl
})
.then(function (note_obj_li_get_result) {
if (note_obj_li_get_result) {
if (try_cache) {
db_save_ae_obj_li__note({
obj_type: 'note',
obj_li: note_obj_li_get_result
});
}
return note_obj_li_get_result;
} else {
return [];
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
});
if (log_lvl) {
console.log('ae_promises.load__note_obj_li:', ae_promises.load__note_obj_li);
}
// if (inc_other_li) {
// // Load the others for the notes
// if (log_lvl) {
// console.log(`Need to load the other list for each note now`);
// }
// for (let i = 0; i < ae_promises.load__note_obj_li.length; i++) {
// let note_obj = ae_promises.load__note_obj_li[i];
// let note_id = note_obj.note_id_random;
// let load_note_other_obj_li = load_ae_obj_li__note_other({
// api_cfg: api_cfg,
// for_obj_type: 'note',
// for_obj_id: note_id,
// params: {qry__enabled: enabled, qry__limit: limit},
// try_cache: try_cache,
// log_lvl: log_lvl
// })
// .then((note_other_obj_li) => {
// if (log_lvl) {
// console.log(`note_other_obj_li = `, note_other_obj_li);
// }
// return note_other_obj_li;
// });
// if (log_lvl) {
// console.log(`load_note_other_obj_li = `, load_note_other_obj_li);
// }
// }
// }
return ae_promises.load__note_obj_li;
}
// Updated 2024-09-25
export async function create_ae_obj__note(
{
api_cfg,
account_id,
data_kv,
params={},
log_lvl=0
}: {
api_cfg: any,
account_id: string,
data_kv: key_val,
params?: key_val,
log_lvl?: number
}
) {
console.log(`*** create_ae_obj__note() *** account_id=${account_id}`);
ae_promises.create__note = await api.create_ae_obj_crud({
api_cfg: api_cfg,
obj_type: 'note',
fields: {
account_id_random: account_id,
...data_kv
},
key: api_cfg.api_crud_super_key,
params: params,
return_obj: true,
log_lvl: log_lvl
})
.then(function (note_obj_create_result) {
if (note_obj_create_result) {
db_save_ae_obj_li__note(
{
obj_type: 'note',
obj_li: [note_obj_create_result]
});
return note_obj_create_result;
} else {
return null;
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
})
.finally(function () {
});
if (log_lvl) {
console.log('ae_promises.create__note:', ae_promises.create__note);
}
return ae_promises.create__note;
}
// Updated 2024-09-25
export async function update_ae_obj__note(
{
api_cfg,
note_id,
data_kv,
params = {},
try_cache = true,
log_lvl = 0
}: {
api_cfg: any,
note_id: string,
data_kv: key_val,
params?: key_val,
try_cache?: boolean,
log_lvl?: number
}
) {
if (log_lvl) {
console.log(`*** update_ae_obj__note() *** note_id=${note_id}`, data_kv);
}
ae_promises.update__note_obj = await api.update_ae_obj_id_crud({
api_cfg: api_cfg,
obj_type: 'note',
obj_id: note_id,
fields: data_kv,
key: api_cfg.api_crud_super_key,
params: params,
return_obj: true,
log_lvl: log_lvl
})
.then(function (note_obj_update_result) {
if (note_obj_update_result) {
if (try_cache) {
db_save_ae_obj_li__note({
obj_type: 'note', obj_li: [note_obj_update_result]
});
}
return note_obj_update_result;
} else {
return null;
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
})
.finally(function () {
});
if (log_lvl) {
console.log('ae_promises.update__note_obj:', ae_promises.update__note_obj);
}
return ae_promises.update__note_obj;
}
// This new function is using CRUD v2. This should allow for more flexibility in the queries.
// Updated 2024-09-25
export async function qry__note(
{
api_cfg,
note_id,
qry_str,
qry_files,
qry_start_datetime, // Example greater than: '2024-10-24'
enabled = 'enabled',
hidden = 'not_hidden',
limit = 50,
offset = 0,
params = {},
try_cache = true,
log_lvl = 0
}: {
api_cfg: any,
note_id: any,
qry_str?: string,
qry_files?: null|boolean,
qry_start_datetime?: null|string, // Greater than this datetime
enabled?: string, // all, disabled, enabled
hidden?: string, // all, hidden, not_hidden
limit?: number,
offset?: number,
params?: any,
try_cache?: boolean,
log_lvl?: number
}
) {
console.log(`*** qry__note() *** note_id=${note_id} qry_str=${qry_str}`);
// let enabled: string = (params.qry__enabled ?? 'enabled'); // all, disabled, enabled
// let hidden: string = (params.qry__hidden ?? 'not_hidden'); // all, hidden, not_hidden
// let limit: number = (params.qry__limit ?? 25); // 99
// let offset: number = (params.qry__offset ?? 0); // 0
let params_json: key_val = {};
// if (qry_str && qry_str.length > 2) {
// params_json['ft_qry'] = {};
// params_json['ft_qry']['default_qry_str'] = qry_str;
// }
params_json['qry'] = [];
if (qry_files === true) {
let qry_param =
{
type: "AND",
field: "file_count_all",
operator: ">",
value: 0
};
params_json['qry'].push(qry_param);
} else if (qry_files === false) {
let qry_param =
{
type: "AND",
field: "file_count_all",
operator: "IS",
value: null
};
params_json['qry'].push(qry_param);
}
if (qry_start_datetime) {
let qry_param =
{
type: "AND",
field: "start_datetime",
operator: ">",
value: qry_start_datetime
};
params_json['qry'].push(qry_param);
}
let order_by_li = {'priority': 'DESC', 'sort': 'DESC', 'start_datetime': 'ASC', 'name': 'ASC', 'updated_on': 'DESC', 'created_on': 'DESC'};
ae_promises.load__note_obj_li = await api.get_ae_obj_li_for_obj_id_crud_v2({
api_cfg: api_cfg,
obj_type: 'note',
for_obj_type: 'account',
for_obj_id: note_id,
use_alt_tbl: true, // NOTE: We want to use the alt table for note searching
use_alt_mdl: false,
use_alt_exp: false,
enabled: enabled,
hidden: hidden,
order_by_li: order_by_li,
limit: limit,
offset: offset,
params_json: params_json,
params: params,
log_lvl: log_lvl
})
.then(function (note_obj_li_get_result) {
if (note_obj_li_get_result) {
db_save_ae_obj_li__note({
obj_type: 'note',
obj_li: note_obj_li_get_result
});
return note_obj_li_get_result;
} else {
return [];
}
});
if (log_lvl) {
console.log('ae_promises.load__note_obj_li:', ae_promises.load__note_obj_li);
}
return ae_promises.load__note_obj_li;
}
// Updated 2024-09-25
// export async function search__note(
// {
// api_cfg,
// account_id,
// poc_agree = null,
// fulltext_search_qry_str,
// ft_other_search_qry_str,
// like_search_qry_str = null,
// file_count = false, // If true then only show those that have a file count
// person_name = null,
// params = {},
// try_cache = true,
// log_lvl = 0
// }: {
// api_cfg: any,
// account_id: any,
// poc_agree?: null|boolean,
// fulltext_search_qry_str?: null|string,
// ft_other_search_qry_str?: null|string,
// like_search_qry_str?: null|string,
// file_count?: boolean,
// person_name?: null|string,
// params?: any,
// try_cache?: boolean,
// log_lvl?: number
// }
// ) {
// console.log(`*** search__note() *** account_id=${account_id}`);
// let enabled: string = (params.qry__enabled ?? 'enabled'); // all, disabled, enabled
// let hidden: string = (params.qry__hidden ?? 'not_hidden'); // all, hidden, not_hidden
// let limit: number = (params.qry__limit ?? 25); // 99
// let offset: number = (params.qry__offset ?? 0); // 0
// let params_json: key_val = {};
// // if (!fulltext_search_qry_str && !like_search_qry_str) {
// // console.log('No search string provided!!!');
// // return false; // Returning false instead of [] because no search was performed.
// // }
// if (fulltext_search_qry_str || ft_other_search_qry_str) {
// params_json['ft_qry'] = {};
// if (fulltext_search_qry_str && fulltext_search_qry_str.length > 2) {
// params_json['ft_qry']['default_qry_str'] = fulltext_search_qry_str;
// }
// if (ft_other_search_qry_str && ft_other_search_qry_str.length > 2) {
// params_json['ft_qry']['note_other_li_qry_str'] = ft_other_search_qry_str;
// }
// }
// // Use the AND (AND LIKE) query
// // if (like_search_qry_str || like_other_search_qry_str) {
// // params_json['and_like'] = {};
// // if (like_search_qry_str && like_search_qry_str.length > 2) {
// // params_json['and_like']['default_qry_str'] = like_search_qry_str;
// // }
// // if (like_other_search_qry_str && like_other_search_qry_str.length > 2) {
// // params_json['and_like']['note_other_li_qry_str'] = like_other_search_qry_str;
// // }
// // }
// // Use the AND (OR LIKE) query
// if (like_search_qry_str || like_other_search_qry_str || like_other_search_qry_str) {
// params_json['or_like'] = {};
// if (like_search_qry_str && like_search_qry_str.length > 2) {
// params_json['or_like']['default_qry_str'] = like_search_qry_str;
// }
// if (like_other_search_qry_str && like_other_search_qry_str.length > 2) {
// params_json['or_like']['note_other_li_qry_str'] = like_other_search_qry_str;
// }
// if (like_other_search_qry_str && like_other_search_qry_str.length > 2) {
// params_json['or_like']['note_other_li_qry_str'] = like_other_search_qry_str;
// }
// }
// params_json['and_qry'] = {};
// if (poc_agree) {
// params_json['and_qry']['poc_agree'] = poc_agree;
// }
// if (file_count) {
// params_json['and_qry']['file_count'] = file_count;
// }
// // This should be using a like with surrounded by %'s
// if (person_name) {
// params_json['and_qry']['note_full_name'] = person_name;
// }
// let order_by_li = {'priority': 'DESC', 'sort': 'DESC', 'name': 'ASC', 'updated_on': 'DESC', 'created_on': 'DESC'};
// ae_promises.load__note_obj_li = await api.get_ae_obj_li_for_obj_id_crud({
// api_cfg: api_cfg,
// obj_type: 'note',
// for_obj_type: 'account',
// for_obj_id: account_id,
// use_alt_table: true, // NOTE: We want to use the alt table for note searching
// use_alt_base: false,
// enabled: enabled,
// hidden: hidden,
// order_by_li: order_by_li,
// limit: limit,
// offset: offset,
// params_json: params_json,
// params: params,
// log_lvl: log_lvl
// })
// .then(function (note_obj_li_get_result) {
// if (note_obj_li_get_result) {
// if (try_cache) {
// db_save_ae_obj_li__note({
// obj_type: 'note',
// obj_li: note_obj_li_get_result
// });
// }
// return note_obj_li_get_result;
// } else {
// return [];
// }
// })
// .catch(function (error) {
// console.log('No results returned or failed.', error);
// })
// .finally(function () {
// });
// if (log_lvl) {
// console.log('ae_promises.load__note_obj_li:', ae_promises.load__note_obj_li);
// }
// return ae_promises.load__note_obj_li;
// }
// This function will loop through the note_obj_li and save each one to the DB.
// Updated 2024-09-25
export function db_save_ae_obj_li__note(
{
obj_type,
obj_li,
log_lvl = 0
}: {
obj_type: string,
obj_li: any,
log_lvl?: number
}
) {
if (log_lvl) {
console.log(`*** db_save_ae_obj_li__note() ***`);
}
if (obj_li && obj_li.length) {
obj_li.forEach(async function (obj: any) {
if (log_lvl) {
console.log(`ae_obj ${obj_type}:`, obj);
}
try {
const id_random = await db_notes.note.put({
id: obj.note_id_random,
note_id: obj.note_id_random,
code: obj.code,
for_type: obj.for_type,
for_id: obj.for_id,
type_code: obj.type_code,
account_id: obj.account_id_random,
person_id: obj.person_id_random,
name: obj.name,
summary: obj.summary,
outline: obj.outline,
// note: obj.note,
note_html: obj.note_html,
note_json: obj.note_json,
start_datetime: obj.start_datetime,
end_datetime: obj.end_datetime,
timezone: obj.timezone,
alert: obj.alert,
alert_msg: obj.alert_msg,
data_json: obj.data_json,
enable: obj.enable,
hide: obj.hide,
priority: obj.priority,
sort: obj.sort,
group: obj.group,
notes: obj.notes,
created_on: obj.created_on,
updated_on: obj.updated_on,
// From SQL view
// note_other_count: obj.note_other_count,
// A key value list of the others
// note_other_kv: obj.note_other_kv,
// note_other_li: obj.note_other_li,
});
// console.log(`Put obj with ID: ${obj.note_id_random} or ${id_random}`);
} catch (error) {
let status = `Failed to put ${obj.note_id_random}: ${error}`;
console.log(status);
}
// const id_random = await db_notes.note.put(obj);
// console.log(`Put obj with ID: ${obj.note_id_random}`);
});
return true;
}
}

View File

@@ -0,0 +1,20 @@
// This file is used to export all the functions that are used for Aether Events related functions.
import {
load_ae_obj_id__note,
load_ae_obj_li__note,
create_ae_obj__note,
update_ae_obj__note,
// qry__note,
db_save_ae_obj_li__note,
} from "$lib/ae_notes__note";
let export_obj = {
load_ae_obj_id__note: load_ae_obj_id__note,
load_ae_obj_li__note: load_ae_obj_li__note,
create_ae_obj__note: create_ae_obj__note,
update_ae_obj__note: update_ae_obj__note,
db_save_ae_obj_li__note: db_save_ae_obj_li__note,
};
export let notes_func = export_obj;

View File

@@ -0,0 +1,70 @@
import { localStorageStore } from '@skeletonlabs/skeleton';
import { writable } from 'svelte/store';
import type { Writable } from 'svelte/store';
import type { key_val } from '$lib/ae_stores';
/* *** BEGIN *** Initialize notes_local_data_struct */
// This is for longer term or sticky app data. This should be stored to *local* storage.
// Updated 2024-08-20
let notes_local_data_struct: key_val = {
ver: '2024-08-20_19',
// Shared
name: 'Aether - Notes (SvelteKit 2.x Svelte 4.x)',
title: `OSIT's Æ Notes`, // &AElig;
mode__edit: false,
mode__debug: false,
};
// console.log(`AE Stores - App Notes Local Storage Data:`, notes_local_data_struct);
// This works and uses *local* storage:
export let notes_loc: Writable<key_val> = localStorageStore('ae_notes_loc', notes_local_data_struct);
// console.log(`AE Stores - App Local Storage Data:`, get(ae_loc));
/* *** BEGIN *** Initialize notes_session_data_struct */
// Temporary app data. This is lost if the page is refreshed or using different tabs/windows. This should be stored to *session* storage.
// Updated 2024-08-20
let notes_session_data_struct: key_val = {
ver: '2024-08-20_19',
log_lvl: 1,
// Shared Triggers
trigger: null,
trigger__note_id: null,
// trigger__note_li: null,
};
// console.log(`AE Stores - App Notes Session Storage Data:`, notes_session_data_struct);
export let notes_sess = writable(notes_session_data_struct);
/* *** BEGIN *** Initialize notes_slct and notes_trigger */
/* The slct and slct_trigger variable should not be stored in local storage. Only use session storage because browser tabs can be open to different notes, badges, exhibits, etc. */
// Intended for temporary session storage.
// Updated 2024-08-20
let notes_slct_obj_template: key_val = {
// Top level
'note_id': null,
'note_obj': {},
'note_obj_li': [],
'lq__note_obj': {}, // Testing passing a LiveQuery object around...
};
// console.log(`AE Stores - Selected Notes Objects:`, notes_slct_obj_template);
// This works, and uses *session* (not local) storage:
export let notes_slct = writable(notes_slct_obj_template);
/* *** BEGIN *** Initialize notes_trigger */
// Intended for temporary session storage.
// Updated 2024-08-20
export let notes_trigger: any = writable(null);
// console.log(`AE Notes Stores - Notes Trigger:`, notes_trigger);

638
src/lib/ae_posts__post.ts Normal file
View File

@@ -0,0 +1,638 @@
import type { key_val } from '$lib/ae_stores';
import { api } from '$lib/api';
import { db_posts } from "$lib/db_posts";
import { load_ae_obj_li__post_comment } from "$lib/ae_posts__post_comment";
let ae_promises: key_val = {};
// Updated 2024-09-25
export async function load_ae_obj_id__post(
{
api_cfg,
post_id,
inc_comment_li = false,
try_cache = true,
log_lvl = 0
}: {
api_cfg: any,
post_id: string,
inc_comment_li?: boolean,
try_cache?: boolean,
log_lvl?: number
}
) {
console.log(`*** load_ae_obj_id__post() *** post_id=${post_id}`);
let params = {};
ae_promises.load__post_obj = await api.get_ae_obj_id_crud({
api_cfg: api_cfg,
obj_type: 'post',
obj_id: post_id, // NOTE: This is the FQDN, not normally the ID.
use_alt_table: true, // NOTE: This will use the table_name_alt value instead of the table_name value in the API config.
use_alt_base: false, // NOTE: This will use the base_name_alt value instead of the base_name value in the API config.
params: params,
log_lvl: log_lvl
})
.then(function (post_obj_get_result) {
if (post_obj_get_result) {
if (try_cache) {
// This is expecting a list
db_save_ae_obj_li__post({
obj_type: 'post',
obj_li: [post_obj_get_result]
});
}
return post_obj_get_result;
} else {
console.log('No results returned.');
return null;
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
});
if (log_lvl) {
console.log('ae_promises.load__post_obj:', ae_promises.load__post_obj);
}
if (inc_comment_li) {
// Load the comments for the post
if (log_lvl) {
console.log(`Need to load the comment list for the post now`);
}
let load_post_comment_obj_li = load_ae_obj_li__post_comment({
api_cfg: api_cfg,
for_obj_type: 'post',
for_obj_id: post_id,
params: {qry__enabled: 'all', qry__limit: 25},
try_cache: try_cache,
log_lvl: log_lvl
})
.then((post_comment_obj_li) => {
if (log_lvl) {
console.log(`post_comment_obj_li = `, post_comment_obj_li);
}
return post_comment_obj_li;
});
if (log_lvl) {
console.log(`post_comment_obj_li = `, load_post_comment_obj_li);
}
ae_promises.load__post_obj.post_comment_li = load_post_comment_obj_li;
}
return ae_promises.load__post_obj;
}
// Updated 2024-09-25
export async function load_ae_obj_li__post(
{
api_cfg,
for_obj_type = 'account',
for_obj_id,
inc_comment_li = false,
order_by_li = {'priority': 'DESC', 'sort': 'DESC', 'updated_on': 'DESC', 'created_on': 'DESC', 'title': 'ASC'},
params = {},
try_cache = true,
log_lvl = 0
}: {
api_cfg: any,
for_obj_type: string,
for_obj_id: string,
inc_comment_li?: boolean,
order_by_li?: key_val,
params?: key_val,
try_cache?: boolean,
log_lvl?: number
}
) {
console.log(`*** load_ae_obj_li__post() *** for_obj_type=${for_obj_type} for_obj_id=${for_obj_id}`);
let enabled: string = (params.qry__enabled ?? 'enabled'); // all, disabled, enabled
let hidden: string = (params.qry__hidden ?? 'not_hidden'); // all, hidden, not_hidden
let limit: number = (params.qry__limit ?? 99); // 99
let offset: number = (params.qry__offset ?? 0); // 0
let params_json: key_val = {};
// console.log('params_json:', params_json);
ae_promises.load__post_obj_li = await api.get_ae_obj_li_for_obj_id_crud({
api_cfg: api_cfg,
obj_type: 'post',
for_obj_type: for_obj_type,
for_obj_id: for_obj_id,
use_alt_table: true, // NOTE: This will use the table_name_alt value instead of the table_name value in the API config.
use_alt_base: false, // NOTE: This will use the base_name_alt value instead of the base_name value
enabled: enabled,
hidden: hidden,
order_by_li: order_by_li,
limit: limit,
offset: offset,
params_json: params_json,
params: params,
log_lvl: log_lvl
})
.then(function (post_obj_li_get_result) {
if (post_obj_li_get_result) {
if (try_cache) {
db_save_ae_obj_li__post({
obj_type: 'post',
obj_li: post_obj_li_get_result
});
}
return post_obj_li_get_result;
} else {
return [];
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
});
if (log_lvl) {
console.log('ae_promises.load__post_obj_li:', ae_promises.load__post_obj_li);
}
if (inc_comment_li) {
// Load the comments for the posts
if (log_lvl) {
console.log(`Need to load the comment list for each post now`);
}
for (let i = 0; i < ae_promises.load__post_obj_li.length; i++) {
let post_obj = ae_promises.load__post_obj_li[i];
let post_id = post_obj.post_id_random;
let load_post_comment_obj_li = load_ae_obj_li__post_comment({
api_cfg: api_cfg,
for_obj_type: 'post',
for_obj_id: post_id,
params: {qry__enabled: enabled, qry__limit: limit},
try_cache: try_cache,
log_lvl: log_lvl
})
.then((post_comment_obj_li) => {
if (log_lvl) {
console.log(`post_comment_obj_li = `, post_comment_obj_li);
}
return post_comment_obj_li;
});
if (log_lvl) {
console.log(`load_post_comment_obj_li = `, load_post_comment_obj_li);
}
}
}
return ae_promises.load__post_obj_li;
}
// Updated 2024-09-25
export async function create_ae_obj__post(
{
api_cfg,
account_id,
data_kv,
params={},
log_lvl=0
}: {
api_cfg: any,
account_id: string,
data_kv: key_val,
params?: key_val,
log_lvl?: number
}
) {
console.log(`*** create_ae_obj__post() *** account_id=${account_id}`);
ae_promises.create__post = await api.create_ae_obj_crud({
api_cfg: api_cfg,
obj_type: 'post',
fields: {
account_id_random: account_id,
...data_kv
},
key: api_cfg.api_crud_super_key,
params: params,
return_obj: true,
log_lvl: log_lvl
})
.then(function (post_obj_create_result) {
if (post_obj_create_result) {
db_save_ae_obj_li__post(
{
obj_type: 'post',
obj_li: [post_obj_create_result]
});
return post_obj_create_result;
} else {
return null;
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
})
.finally(function () {
});
if (log_lvl) {
console.log('ae_promises.create__post:', ae_promises.create__post);
}
return ae_promises.create__post;
}
// Updated 2024-09-25
export async function update_ae_obj__post(
{
api_cfg,
post_id,
data_kv,
params = {},
try_cache = true,
log_lvl = 0
}: {
api_cfg: any,
post_id: string,
data_kv: key_val,
params?: key_val,
try_cache?: boolean,
log_lvl?: number
}
) {
if (log_lvl) {
console.log(`*** update_ae_obj__post() *** post_id=${post_id}`, data_kv);
}
ae_promises.update__post_obj = await api.update_ae_obj_id_crud({
api_cfg: api_cfg,
obj_type: 'post',
obj_id: post_id,
fields: data_kv,
key: api_cfg.api_crud_super_key,
params: params,
return_obj: true,
log_lvl: log_lvl
})
.then(function (post_obj_update_result) {
if (post_obj_update_result) {
if (try_cache) {
db_save_ae_obj_li__post({
obj_type: 'post', obj_li: [post_obj_update_result]
});
}
return post_obj_update_result;
} else {
return null;
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
})
.finally(function () {
});
if (log_lvl) {
console.log('ae_promises.update__post_obj:', ae_promises.update__post_obj);
}
return ae_promises.update__post_obj;
}
// This new function is using CRUD v2. This should allow for more flexibility in the queries.
// Updated 2024-09-25
export async function qry__post(
{
api_cfg,
account_id,
qry_str,
qry_files,
qry_start_datetime, // Example greater than: '2024-10-24'
enabled = 'enabled',
hidden = 'not_hidden',
limit = 50,
offset = 0,
params = {},
try_cache = true,
log_lvl = 0
}: {
api_cfg: any,
account_id: any,
qry_str?: string,
qry_files?: null|boolean,
qry_start_datetime?: null|string, // Greater than this datetime
enabled?: string, // all, disabled, enabled
hidden?: string, // all, hidden, not_hidden
limit?: number,
offset?: number,
params?: any,
try_cache?: boolean,
log_lvl?: number
}
) {
console.log(`*** qry__post() *** account_id=${account_id} qry_str=${qry_str}`);
// let enabled: string = (params.qry__enabled ?? 'enabled'); // all, disabled, enabled
// let hidden: string = (params.qry__hidden ?? 'not_hidden'); // all, hidden, not_hidden
// let limit: number = (params.qry__limit ?? 25); // 99
// let offset: number = (params.qry__offset ?? 0); // 0
let params_json: key_val = {};
// if (qry_str && qry_str.length > 2) {
// params_json['ft_qry'] = {};
// params_json['ft_qry']['default_qry_str'] = qry_str;
// }
params_json['qry'] = [];
if (qry_files === true) {
let qry_param =
{
type: "AND",
field: "file_count_all",
operator: ">",
value: 0
};
params_json['qry'].push(qry_param);
} else if (qry_files === false) {
let qry_param =
{
type: "AND",
field: "file_count_all",
operator: "IS",
value: null
};
params_json['qry'].push(qry_param);
}
if (qry_start_datetime) {
let qry_param =
{
type: "AND",
field: "start_datetime",
operator: ">",
value: qry_start_datetime
};
params_json['qry'].push(qry_param);
}
let order_by_li = {'priority': 'DESC', 'sort': 'DESC', 'updated_on': 'DESC', 'created_on': 'DESC', 'title': 'ASC'};
ae_promises.load__post_obj_li = await api.get_ae_obj_li_for_obj_id_crud_v2({
api_cfg: api_cfg,
obj_type: 'post',
for_obj_type: 'account',
for_obj_id: account_id,
use_alt_tbl: true, // NOTE: We want to use the alt table for post searching
use_alt_mdl: false,
use_alt_exp: false,
enabled: enabled,
hidden: hidden,
order_by_li: order_by_li,
limit: limit,
offset: offset,
params_json: params_json,
params: params,
log_lvl: log_lvl
})
.then(function (post_obj_li_get_result) {
if (post_obj_li_get_result) {
db_save_ae_obj_li__post({
obj_type: 'post',
obj_li: post_obj_li_get_result
});
return post_obj_li_get_result;
} else {
return [];
}
});
if (log_lvl) {
console.log('ae_promises.load__post_obj_li:', ae_promises.load__post_obj_li);
}
return ae_promises.load__post_obj_li;
}
// Updated 2024-09-25
// export async function search__post(
// {
// api_cfg,
// account_id,
// poc_agree = null,
// fulltext_search_qry_str,
// ft_comment_search_qry_str,
// like_search_qry_str = null,
// file_count = false, // If true then only show those that have a file count
// person_name = null,
// params = {},
// try_cache = true,
// log_lvl = 0
// }: {
// api_cfg: any,
// account_id: any,
// poc_agree?: null|boolean,
// fulltext_search_qry_str?: null|string,
// ft_comment_search_qry_str?: null|string,
// like_search_qry_str?: null|string,
// file_count?: boolean,
// person_name?: null|string,
// params?: any,
// try_cache?: boolean,
// log_lvl?: number
// }
// ) {
// console.log(`*** search__post() *** account_id=${account_id}`);
// let enabled: string = (params.qry__enabled ?? 'enabled'); // all, disabled, enabled
// let hidden: string = (params.qry__hidden ?? 'not_hidden'); // all, hidden, not_hidden
// let limit: number = (params.qry__limit ?? 25); // 99
// let offset: number = (params.qry__offset ?? 0); // 0
// let params_json: key_val = {};
// // if (!fulltext_search_qry_str && !like_search_qry_str) {
// // console.log('No search string provided!!!');
// // return false; // Returning false instead of [] because no search was performed.
// // }
// if (fulltext_search_qry_str || ft_comment_search_qry_str) {
// params_json['ft_qry'] = {};
// if (fulltext_search_qry_str && fulltext_search_qry_str.length > 2) {
// params_json['ft_qry']['default_qry_str'] = fulltext_search_qry_str;
// }
// if (ft_comment_search_qry_str && ft_comment_search_qry_str.length > 2) {
// params_json['ft_qry']['post_comment_li_qry_str'] = ft_comment_search_qry_str;
// }
// }
// // Use the AND (AND LIKE) query
// // if (like_search_qry_str || like_comment_search_qry_str) {
// // params_json['and_like'] = {};
// // if (like_search_qry_str && like_search_qry_str.length > 2) {
// // params_json['and_like']['default_qry_str'] = like_search_qry_str;
// // }
// // if (like_comment_search_qry_str && like_comment_search_qry_str.length > 2) {
// // params_json['and_like']['post_comment_li_qry_str'] = like_comment_search_qry_str;
// // }
// // }
// // Use the AND (OR LIKE) query
// if (like_search_qry_str || like_comment_search_qry_str || like_comment_search_qry_str) {
// params_json['or_like'] = {};
// if (like_search_qry_str && like_search_qry_str.length > 2) {
// params_json['or_like']['default_qry_str'] = like_search_qry_str;
// }
// if (like_comment_search_qry_str && like_comment_search_qry_str.length > 2) {
// params_json['or_like']['post_comment_li_qry_str'] = like_comment_search_qry_str;
// }
// if (like_comment_search_qry_str && like_comment_search_qry_str.length > 2) {
// params_json['or_like']['post_comment_li_qry_str'] = like_comment_search_qry_str;
// }
// }
// params_json['and_qry'] = {};
// if (poc_agree) {
// params_json['and_qry']['poc_agree'] = poc_agree;
// }
// if (file_count) {
// params_json['and_qry']['file_count'] = file_count;
// }
// // This should be using a like with surrounded by %'s
// if (person_name) {
// params_json['and_qry']['post_full_name'] = person_name;
// }
// let order_by_li = {'priority': 'DESC', 'sort': 'DESC', 'name': 'ASC', 'updated_on': 'DESC', 'created_on': 'DESC'};
// ae_promises.load__post_obj_li = await api.get_ae_obj_li_for_obj_id_crud({
// api_cfg: api_cfg,
// obj_type: 'post',
// for_obj_type: 'account',
// for_obj_id: account_id,
// use_alt_table: true, // NOTE: We want to use the alt table for post searching
// use_alt_base: false,
// enabled: enabled,
// hidden: hidden,
// order_by_li: order_by_li,
// limit: limit,
// offset: offset,
// params_json: params_json,
// params: params,
// log_lvl: log_lvl
// })
// .then(function (post_obj_li_get_result) {
// if (post_obj_li_get_result) {
// if (try_cache) {
// db_save_ae_obj_li__post({
// obj_type: 'post',
// obj_li: post_obj_li_get_result
// });
// }
// return post_obj_li_get_result;
// } else {
// return [];
// }
// })
// .catch(function (error) {
// console.log('No results returned or failed.', error);
// })
// .finally(function () {
// });
// if (log_lvl) {
// console.log('ae_promises.load__post_obj_li:', ae_promises.load__post_obj_li);
// }
// return ae_promises.load__post_obj_li;
// }
// This function will loop through the post_obj_li and save each one to the DB.
// Updated 2024-09-25
export function db_save_ae_obj_li__post(
{
obj_type,
obj_li,
log_lvl = 0
}: {
obj_type: string,
obj_li: any,
log_lvl?: number
}
) {
if (log_lvl) {
console.log(`*** db_save_ae_obj_li__post() ***`);
}
if (obj_li && obj_li.length) {
obj_li.forEach(async function (obj: any) {
if (log_lvl) {
console.log(`ae_obj ${obj_type}:`, obj);
}
try {
const id_random = await db_posts.post.put({
id: obj.post_id_random,
post_id: obj.post_id_random,
account_id: obj.account_id_random,
topic_id: obj.topic_id,
topic: obj.topic,
topic_name: obj.topic_name,
title: obj.title,
content: obj.content,
anonymous: obj.anonymous,
full_name: obj.full_name,
email: obj.email,
enable_comments: obj.enable_comments,
archive: obj.archive,
archive_on: obj.archive_on,
cfg_json: obj.cfg_json,
enable: obj.enable,
hide: obj.hide,
priority: obj.priority,
sort: obj.sort,
group: obj.group,
notes: obj.notes,
created_on: obj.created_on,
updated_on: obj.updated_on,
// From SQL view
// post_comment_count: obj.post_comment_count,
// A key value list of the comments
// post_comment_kv: obj.post_comment_kv,
// post_comment_li: obj.post_comment_li,
});
// console.log(`Put obj with ID: ${obj.post_id_random} or ${id_random}`);
} catch (error) {
let status = `Failed to put ${obj.post_id_random}: ${error}`;
console.log(status);
}
// const id_random = await db_posts.post.put(obj);
// console.log(`Put obj with ID: ${obj.post_id_random}`);
});
return true;
}
}

View File

@@ -0,0 +1,306 @@
import type { key_val } from '$lib/ae_stores';
import { api } from '$lib/api';
import { db_posts } from "$lib/db_posts";
let ae_promises: key_val = {};
// Updated 2024-09-25
export async function load_ae_obj_id__post_comment(
{
api_cfg,
post_comment_id,
try_cache = true,
log_lvl = 0
}: {
api_cfg: any,
post_comment_id: string,
try_cache?: boolean,
log_lvl?: number
}
) {
console.log(`*** load_ae_obj_id__post_comment() *** post_comment_id=${post_comment_id}`);
let params = {};
ae_promises.load__post_comment_obj = await api.get_ae_obj_id_crud({
api_cfg: api_cfg,
obj_type: 'post_comment',
obj_id: post_comment_id, // NOTE: This is the FQDN, not normally the ID.
use_alt_table: false, // NOTE: This will use the table_name_alt value instead of the table_name value in the API config.
use_alt_base: false, // NOTE: This will use the base_name_alt value instead of the base_name value
params: params,
log_lvl: log_lvl
})
.then(function (post_comment_obj_get_result) {
if (post_comment_obj_get_result) {
if (try_cache) {
// This is expecting a list
db_save_ae_obj_li__post_comment({
obj_type: 'post_comment',
obj_li: [post_comment_obj_get_result]
});
}
return post_comment_obj_get_result;
} else {
console.log('No results returned.');
return null;
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
});
return ae_promises.load__post_comment_obj;
}
// Updated 2024-09-25
export async function load_ae_obj_li__post_comment(
{
api_cfg,
for_obj_type = 'post',
for_obj_id,
order_by_li = {'priority': 'DESC', 'sort': 'DESC', 'updated_on': 'DESC', 'created_on': 'DESC', 'title': 'ASC'},
params = {},
try_cache = true,
log_lvl = 0
}: {
api_cfg: any,
for_obj_type: string,
for_obj_id: string,
order_by_li?: key_val,
params?: key_val,
try_cache?: boolean,
log_lvl?: number
}
) {
console.log(`*** load_ae_obj_li__post_comment() *** for_obj_type=${for_obj_type} for_obj_id=${for_obj_id}`);
let enabled: string = (params.qry__enabled ?? 'enabled'); // all, disabled, enabled
let hidden: string = (params.qry__hidden ?? 'not_hidden'); // all, hidden, not_hidden
let limit: number = (params.qry__limit ?? 99); // 99
let offset: number = (params.qry__offset ?? 0); // 0
let params_json: key_val = {};
// console('params_json:', params_json);
ae_promises.load__post_comment_obj_li = await api.get_ae_obj_li_for_obj_id_crud({
api_cfg: api_cfg,
obj_type: 'post_comment',
for_obj_type: for_obj_type,
for_obj_id: for_obj_id,
use_alt_table: true, // NOTE: This will use the table_name_alt value instead of the table_name value in the API config.
use_alt_base: false, // NOTE: This will use the base_name_alt value instead of the base_name value
enabled: enabled,
hidden: hidden,
order_by_li: order_by_li,
limit: limit,
offset: offset,
params_json: params_json,
params: params,
log_lvl: log_lvl
})
.then(function (post_comment_obj_li_get_result) {
if (post_comment_obj_li_get_result) {
if (try_cache) {
db_save_ae_obj_li__post_comment({
obj_type: 'post_comment', obj_li: post_comment_obj_li_get_result
});
}
return post_comment_obj_li_get_result;
} else {
return [];
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
});
if (log_lvl) {
console.log('ae_promises.load__post_comment_obj_li:', ae_promises.load__post_comment_obj_li);
}
return ae_promises.load__post_comment_obj_li;
}
// Updated 2024-09-25
export async function create_ae_obj__post_comment(
{
api_cfg,
post_id,
data_kv,
params={},
log_lvl=0
}: {
api_cfg: any,
post_id: string,
data_kv: key_val,
params?: key_val,
log_lvl?: number
}
) {
console.log(`*** create_ae_obj__post_comment() *** post_id=${post_id}`);
ae_promises.create__post_comment = await api.create_ae_obj_crud({
api_cfg: api_cfg,
obj_type: 'post_comment',
fields: {
post_id_random: post_id,
...data_kv
},
key: api_cfg.api_crud_super_key,
params: params,
return_obj: true,
log_lvl: log_lvl
})
.then(function (post_comment_obj_create_result) {
if (post_comment_obj_create_result) {
db_save_ae_obj_li__post_comment(
{
obj_type: 'post_comment',
obj_li: [post_comment_obj_create_result]
});
return post_comment_obj_create_result;
} else {
return null;
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
})
.finally(function () {
});
if (log_lvl) {
console.log('ae_promises.create__post_comment:', ae_promises.create__post_comment);
}
return ae_promises.create__post_comment;
}
// Updated 2024-09-25
export async function update_ae_obj__post_comment(
{
api_cfg,
post_comment_id,
data_kv,
params = {},
try_cache = true,
log_lvl = 0
}: {
api_cfg: any,
post_comment_id: string,
data_kv: key_val,
params?: key_val,
try_cache?: boolean,
log_lvl?: number
}
) {
if (log_lvl) {
console.log(`*** update_ae_obj__post_comment() *** post_comment_id=${post_comment_id}`, data_kv);
}
ae_promises.update__post_comment_obj = await api.update_ae_obj_id_crud({
api_cfg: api_cfg,
obj_type: 'post_comment',
obj_id: post_comment_id,
fields: data_kv,
key: api_cfg.api_crud_super_key,
params: params,
return_obj: true,
log_lvl: log_lvl
})
.then(function (post_comment_obj_update_result) {
if (post_comment_obj_update_result) {
if (try_cache) {
db_save_ae_obj_li__post_comment({
obj_type: 'post_comment', obj_li: [post_comment_obj_update_result]
});
}
return post_comment_obj_update_result;
} else {
return null;
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
})
.finally(function () {
});
if (log_lvl) {
console.log('ae_promises.update__post_comment_obj:', ae_promises.update__post_comment_obj);
}
return ae_promises.update__post_comment_obj;
}
// This function will loop through the post_comment_obj_li and save each one to the DB.
// Updated 2024-09-25
export function db_save_ae_obj_li__post_comment(
{
obj_type,
obj_li,
log_lvl=0
}: {
obj_type: string,
obj_li: any,
log_lvl?: number
}
) {
if (log_lvl) {
console.log(`*** db_save_ae_obj_li__post_comment() ***`);
}
if (obj_li && obj_li.length) {
obj_li.forEach(async function (obj: any) {
if (log_lvl) {
console.log(`ae_obj ${obj_type}:`, obj);
}
try {
const id_random = await db_posts.comment.put({
id: obj.post_comment_id_random,
post_comment_id: obj.post_comment_id_random,
post_id: obj.post_id_random,
// name: obj.name,
// summary: obj.summary,
title: obj.title,
content: obj.content,
anonymous: obj.anonymous,
full_name: obj.full_name,
email: obj.email,
cfg_json: obj.cfg_json,
enable: obj.enable,
hide: obj.hide,
priority: obj.priority,
sort: obj.sort,
group: obj.group,
notes: obj.notes,
created_on: obj.created_on,
updated_on: obj.updated_on,
// From SQL view
});
// console.log(`Put obj with ID: ${obj.post_comment_id_random} or ${id_random}`);
} catch (error) {
let status = `Failed to put ${obj.post_comment_id_random}: ${error}`;
console.log(status);
}
// const id_random = await db_posts.comment.put(obj);
// console.log(`Put obj with ID: ${obj.post_comment_id_random}`);
});
return true;
}
}

View File

@@ -0,0 +1,36 @@
// This file is used to export all the functions that are used for Aether Posts related functions.
import {
load_ae_obj_id__post,
load_ae_obj_li__post,
create_ae_obj__post,
update_ae_obj__post,
// qry__post,
db_save_ae_obj_li__post,
} from "$lib/ae_posts__post";
import {
load_ae_obj_id__post_comment,
load_ae_obj_li__post_comment,
create_ae_obj__post_comment,
update_ae_obj__post_comment,
// qry__post_comment,
db_save_ae_obj_li__post_comment,
} from "$lib/ae_posts__post_comment";
let export_obj = {
load_ae_obj_id__post: load_ae_obj_id__post,
load_ae_obj_li__post: load_ae_obj_li__post,
create_ae_obj__post: create_ae_obj__post,
update_ae_obj__post: update_ae_obj__post,
db_save_ae_obj_li__post: db_save_ae_obj_li__post,
load_ae_obj_id__post_comment: load_ae_obj_id__post_comment,
load_ae_obj_li__post_comment: load_ae_obj_li__post_comment,
create_ae_obj__post_comment: create_ae_obj__post_comment,
update_ae_obj__post_comment: update_ae_obj__post_comment,
db_save_ae_obj_li__post_comment: db_save_ae_obj_li__post_comment,
};
export let posts_func = export_obj;

View File

@@ -0,0 +1,120 @@
import type { key_val } from '$lib/ae_stores';
import { api } from '$lib/api';
import type { log } from 'console';
// import { liveQuery } from "dexie";
// import { db_core } from "$lib/db_core";
// let example_li = liveQuery(
// () => db_core.sponsorships.toArray()
// );
let ae_promises: key_val = {}; // Promise<any>;
// Updated 2024-03-29
async function handle_load_ae_obj_id__sponsorship_cfg(
{
api_cfg,
sponsorship_cfg_id,
try_cache=false,
log_lvl=0
}: {
api_cfg: any,
sponsorship_cfg_id: string,
try_cache: boolean,
log_lvl: number
}
) {
console.log(`*** handle_load_ae_obj_id__sponsorship_cfg() *** sponsorship_cfg_id=${sponsorship_cfg_id}`);
if (!api_cfg.account_id) {
console.log(`*ae_func* No account_id found in API config!'`);
return false;
}
let params = {};
// ae_loc.hub.sponsorships.qry_status = 'loading';
ae_promises.load__sponsorship_cfg_obj = api.get_ae_obj_id_crud({
api_cfg: api_cfg,
obj_type: 'sponsorship_cfg',
obj_id: sponsorship_cfg_id,
use_alt_table: false, // NOTE: This will use the table_name_alt value instead of the table_name value in the API config.
use_alt_base: false, // NOTE: This will use the base_name_alt value instead of the base_name value in the API config.
params: params,
log_lvl: log_lvl
})
.then(function (sponsorship_cfg_obj_get_result) {
if (sponsorship_cfg_obj_get_result) {
if (log_lvl) {
console.log(`*ae_func* Got a result for sponsorship_cfg_id ${sponsorship_cfg_id}`);
} else if (log_lvl > 1) {
console.log(`*ae_func* Got a result for sponsorship_cfg_id ${sponsorship_cfg_id}:`, sponsorship_cfg_obj_get_result);
}
return sponsorship_cfg_obj_get_result;
} else {
console.log('No results returned.');
return null;
}
})
.catch(function (error) {
console.log('No results returned or failed.', error);
});
return ae_promises.load__sponsorship_cfg_obj;
}
async function handle_download_export__sponsorship(
{
api_cfg,
account_id,
file_type='CSV', // 'CSV' or 'Excel'
return_file=true,
filename='no_filename.csv',
auto_download=false,
params={}, // key value object is expected
log_lvl=0
}: {
api_cfg: any,
account_id: string,
file_type?: string,
return_file?: boolean,
filename?: string,
auto_download?: boolean,
params?: key_val,
log_lvl?: number
}
) {
console.log('*** stores_event_api.js: get_sponsorship_export() ***');
const endpoint = `/v2/crud/sponsorship/list`;
params['for_obj_type'] = 'account';
params['for_obj_id'] = account_id;
if (file_type == 'CSV' || file_type == 'Excel') {
params['file_type'] = file_type;
}
params['return_file'] = true;
ae_promises.download__sponsorship_export_file = await api.get_object({
api_cfg: api_cfg,
endpoint: endpoint,
params: params,
return_blob: return_file,
filename: filename,
auto_download: auto_download,
log_lvl: log_lvl
});
console.log('ae_promises.download__sponsorship_export_file:', ae_promises.download__sponsorship_export_file);
return ae_promises.download__sponsorship_export_file;
}
let export_obj = {
handle_load_ae_obj_id__sponsorship_cfg: handle_load_ae_obj_id__sponsorship_cfg,
handle_download_export__sponsorship: handle_download_export__sponsorship,
};
export let spons_func = export_obj;

358
src/lib/ae_stores.ts Normal file
View File

@@ -0,0 +1,358 @@
import { localStorageStore } from '@skeletonlabs/skeleton';
import { readable, writable } from 'svelte/store';
import type { Readable, Writable } from 'svelte/store';
import { PUBLIC_TESTING, PUBLIC_AE_API_PROTOCOL, PUBLIC_AE_API_SERVER, PUBLIC_AE_API_BAK_SERVER, PUBLIC_AE_API_PORT, PUBLIC_AE_API_PATH, PUBLIC_AE_API_SECRET_KEY, PUBLIC_AE_API_CRUD_SUPER_KEY, PUBLIC_AE_NO_ACCOUNT_ID, PUBLIC_AE_NO_ACCOUNT_ID_TOKEN, PUBLIC_AE_ACCOUNT_ID, PUBLIC_AE_EVENT_ID, PUBLIC_AE_SPONSORSHIP_CFG_ID } from '$env/static/public';
console.log(`AE Stores - PUBLIC_TESTING:`, PUBLIC_TESTING);
const api_server_fqdn = PUBLIC_AE_API_SERVER; // 'api.oneskyit.com'
const api_base_url = `${PUBLIC_AE_API_PROTOCOL}://${PUBLIC_AE_API_SERVER}:${PUBLIC_AE_API_PORT}${PUBLIC_AE_API_PATH}`;
const api_base_url_bak = `${PUBLIC_AE_API_PROTOCOL}://${PUBLIC_AE_API_BAK_SERVER}:${PUBLIC_AE_API_PORT}${PUBLIC_AE_API_PATH}`;
const api_secret_key = PUBLIC_AE_API_SECRET_KEY;
const api_crud_super_key = PUBLIC_AE_API_CRUD_SUPER_KEY;
// const ae_account_id = PUBLIC_AE_ACCOUNT_ID;
let ae_account_id: null|string = null;
const ae_no_account_id = PUBLIC_AE_NO_ACCOUNT_ID;
const ae_no_account_id_token = PUBLIC_AE_NO_ACCOUNT_ID_TOKEN;
const ae_event_id = PUBLIC_AE_EVENT_ID;
const ae_sponsorship_cfg_id = PUBLIC_AE_SPONSORSHIP_CFG_ID;
// import { getStores, navigating, page, updated } from '$app/stores';
// import { assets, base, resolveRoute } from '$app/paths';
// console.log(page.path); // Everything after the domain name
// console.log(import.meta.env.MODE);
// console.log(import.meta.env.BASE_URL);
// Export the key_val type for use in other files.
export type key_val = {
[key: string]: any; // variable key
// name: string;
};
// export type key_val = key_val;
// import { html__not_set, classes__events_pres_mgmt_menu } from './ae_string_snippets';
import {string_snippets} from './ae_string_snippets';
export let ae_snip = string_snippets;
// export let ae_snip =
// {
// 'not_set': html__not_set,
// 'classes__events_pres_mgmt_menu': classes__events_pres_mgmt_menu
// };
// Set the version for the app data. Changing this should force a notification and ask the user to clear and reload the page.
let ver = '2024-08-21_1736';
let ver_idb = '2024-08-21_1735';
// *** BEGIN *** Longer-term app data. This should be stored to local storage.
export let ae_app_local_data_struct: key_val = {
'ver': '2024-08-16_1821',
'ver_idb': '2024-08-16_1826', // Clear if date IndexedDB version
name: 'Aether - App Hub (SvelteKit 2.x Svelte 4.x)',
theme: 'light',
iframe: false,
title: `OSIT's Æ`, // - Dev SvelteKit`, // &AElig;
debug: false, // A simple flag to know if we should show debug information.
edit_mode: false, // A simple flag to know if we should show edit mode options.
sync_local_config: true, // A simple flag to know if we should sync local config with the remote API server.
'account_id': ae_account_id, // OSIT Demo _XY7DXtc9MY
'account_code': 'not_set',
'account_name': 'Account Name Not Set',
'allow_access': false, // Set to key if access is allowed.
'site_domain': null, // https://example.com, https://dev.example.com, etc.
'site_access_key': null,
'site_domain_access_key': null,
'site_cfg_json': {
slct__event_id: null,
slct__event_badge_template_id: null,
slct__sponsorship_cfg_id: null,
header_image_path: null,
},
// The site access codes can be pulled from the site records for an account.
'site_access_code_kv': {
// 'manager': '10240',
'administrator': '11500',
'trusted': '19111',
'public': 'public1980',
'authenticated': 'auth1980'
},
// 'manager_passcode': '10240',
// 'administrator_passcode': '11500',
// 'trusted_passcode': '19111',
// 'authenticated_passcode': 'auth2024',
'access_type': 'anonymous',
'administrator_access': false,
'trusted_access': false,
'public_access': false,
'authenticated_access': false,
'anonymous_access': true,
'user_email': null, // Currently used with Sponsorships only?
'qry__enabled': 'enabled', // all, disabled, enabled
'qry__hidden': 'not_hidden', // all, hidden, not_hidden
'qry__limit': 20,
'qry__offset': 0,
qr_scanner_version: 'one',
'admin': {
show_element__sql_qry: false,
show_element__sql_qry_results: false,
},
'ds': {},
'hub': {
'show_element__cfg': true,
'show_element__cfg_detail': false,
'show_element__access_type': true,
'theme_mode': 'light',
'theme_name': 'wintry', // wintry
'classes__form': 'border border-surface-200 p-4 space-y-4 rounded-container-token',
'qr': {},
},
'mod': {
'archives': {},
'events': {
'event_id': null,
show_edit__event_presenter_obj: false,
show_list__event_presenter_obj_li: true,
show_view__event_presenter_obj: false,
submit_status: null, // 'saving', 'created', 'updated'
// Badge Printing
// Lead Retrievals
// Presentation Management
// Speakers Management
'default_session_id': null, // Assign to presenters by default
// other
},
'journals': {},
'posts': {},
'sponsorships': {
'cfg_id': ae_sponsorship_cfg_id,
for_type: null,
for_id: null,
level_guest_max_li: {
0: 0,
1: 4, // CHOW 2024 - Friend
2: 8, // CHOW 2024 - Supporter
3: 8, // CHOW 2024 - Advocate
4: 8, // CHOW 2024 - Champion
5: 8, // CHOW 2024 - Presenting Partner
6: 16, // CHOW 2024 - Signature Partner
7: 16, // CHOW 2024 - Premier Partner
},
show_edit__sponsorship_obj: false,
show_list__sponsorship_obj_li: true,
show_view__sponsorship_obj: false,
show_question__accommodations: false,
submit_status: null, // 'saving', 'created', 'updated'
},
'testing': {},
},
'person': {
show_content__person_page_help: false,
},
test: true,
}
// console.log(`AE Stores - App Local Storage Data:`, ae_app_local_data_struct);
// This works, but does not uses local storage:
// export let ae_loc = writable(ae_app_local_data_struct);
// This works and uses local storage:
export let ae_loc: Writable<key_val> = localStorageStore('ae_loc', ae_app_local_data_struct);
// console.log(`AE Stores - App Local Storage Data:`, get(ae_loc));
// *** BEGIN *** Temporary app data. This should be stored to session storage.
export let ae_app_session_data_struct: key_val = {
'ver': '2024-02-27_13',
// ver_idb: ver_idb,
log_lvl: 0,
// 'name': 'Aether App Template',
// 'theme': 'light',
// 'account_id': ae_account_id,
'ds': {
'submit_status': null,
},
'ds_loaded': {
},
'hub': {
'show_xyz': null,
},
'mod': {
'archives': {},
'events': {
// Badge Printing
// Lead Retrievals
// Presentation Management
// Speakers Management
// other
},
'journals': {},
'posts': {},
'sponsorships': {
disable_submit__sponsorship_obj: false,
slct__level_num: 0,
show_question__accommodations: false,
submit_status: null, // 'saving', 'created', 'updated', 'saved'
},
'testing': {},
},
'person': {
show_report__person_li: false,
qry_limit__people: 100,
},
'download': {},
// For API download and upload progress status per file.
'api_download_kv': {},
// Example: {example_file_id: {status: 'downloading', endpoint: '/event/file/abc123/download', filename: 'example_file_name.ext', size_total: 0, size_loaded: 0, percent_completed: 0}}
'api_upload_kv': {}, // {example_temp_id: {status: 'uploading', endpoint: '/event/file/abc123/upload', filename: 'example_file_name.ext', size_total: 0, size_loaded: 0, percent_completed: 0}}
test: true,
};
// console.log(`AE Stores - App Session Storage Data:`, ae_app_session_data_struct);
export let ae_sess = writable(ae_app_session_data_struct);
// *** BEGIN *** Temporary API data. This should be stored to session storage.
export let ae_api_data_struct: key_val = {
'ver': '2024-08-11_11',
'fqdn': api_server_fqdn,
'base_url': api_base_url,
'base_url_bak': api_base_url_bak,
'api_secret_key': api_secret_key, // 'YOUR_API_SECRET_KEY',
'api_secret_key_bak': api_secret_key, // 'YOUR_API_SECRET_KEY',
'api_crud_super_key': api_crud_super_key, // 'YOUR_SUPER_KEY' 'zp5PtX4zUsI'
'headers': {},
'account_id': ae_account_id,
};
let ae_api_headers: key_val = {};
ae_api_headers['Access-Control-Allow-Origin'] = '*';
ae_api_headers['content-type'] = 'application/json';
ae_api_headers['x-aether-api-key'] = ae_api_data_struct.api_secret_key;
ae_api_headers['x-aether-api-token'] = 'fake-temp-token';
ae_api_headers['x-aether-api-expire-on'] = '';
if (ae_account_id) {
ae_api_headers['x-account-id'] = ae_account_id;
} else {
// ae_api_headers['x-account-id'] = ;
}
if (ae_no_account_id) {
ae_api_headers['x-no-account-id'] = ae_no_account_id;
}
ae_api_data_struct['headers'] = ae_api_headers;
// console.log(`AE Stores - API Data:`, ae_api_data_struct);
export let ae_api = writable(ae_api_data_struct);
// *** BEGIN *** Trigger to update the slct variables and other things.
let ae_trig_template: key_val = {};
export let ae_trig = writable(ae_trig_template);
/* *** BEGIN *** Initialize slct and slct_trigger */
/* The slct and slct_trigger variable should not be stored in local storage. Only use session storage because browser tabs can be open to different accounts, events, sponsorships, etc. */
// Intended for temporary session storage.
// Updated 2024-03-15
let slct_obj_template: key_val = {
'account_id': ae_account_id,
'account_obj': {},
'event_id': null,
'event_obj': {},
'event_obj_li': [],
// 'event_exhibit_id': null,
// 'event_exhibit_obj': {},
// 'event_exhibit_obj_li': [],
'event_presentation_id': null,
'event_presentation_obj': {},
'event_presentation_obj_li': [],
'event_presenter_id': null,
'event_presenter_obj': {},
'event_presenter_obj_li': [],
'event_session_id': null,
'event_session_obj': {},
'event_session_obj_li': [],
'sponsorship_id': null,
'sponsorship_obj': {},
'sponsorship_obj_li': [],
'sponsorship_cfg_id': ae_sponsorship_cfg_id,
'sponsorship_cfg_obj': {},
'sponsorship_cfg_obj_li': [],
'post_id': null,
'post_obj': {},
'post_obj_li': [],
'post_comment_id': null,
'post_comment_obj': {},
'post_comment_obj_li': []
};
// console.log(`AE Stores - Selected Objects:`, slct_obj_template);
// This works, and uses *session* (not local) storage:
export let slct = writable(slct_obj_template);
// This works and uses *local* storage:
// export let slct: Writable<key_val> = localStorageStore('ae_slct', slct_obj_template);
/* *** BEGIN *** Initialize slct_trigger */
// Intended for temporary session storage.
// Updated 2024-02-27
export let slct_trigger: any = writable(null);
// console.log(`AE Stores - Selected Trigger:`, slct_trigger);
/* *** BEGIN *** Create time variable */
// Updated 2020
export const time = readable(new Date(), function start(set) {
const interval = setInterval(() => {
set(new Date());
}, 1000);
return function stop() {
clearInterval(interval);
};
});

View File

@@ -0,0 +1,32 @@
// These are shared snippets of text, This is mostly HTML and CSS.
export let string_snippets: any = {};
string_snippets['html__not_set'] = `
<span
class="text-sm text-gray-500 bg-gray-100 p-1 rounded-md border border-gray-200"
>-- not set --
</span>
`;
string_snippets['classes__core_menu'] = 'flex flex-col items-center space-y-1 border border-blue-200 rounded-md py-1 px-2 hover:bg-blue-100';
string_snippets['classes__core_menu__button'] = 'btn btn-sm mx-1 variant-soft-tertiary text-info-300 hover:text-info-800';
string_snippets['classes__core_menu__button_highlight'] = 'btn btn-sm mx-1 variant-filled-tertiary text-info-300 hover:text-info-800';
string_snippets['classes__core_menu__button_warning'] = 'btn btn-sm mx-1 variant-soft-warning text-info-300 hover:text-info-800';
// 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-glass-secondary hover:variant-filled-secondary';
string_snippets['classes__events_pres_mgmt_menu__button_special'] = 'btn btn-sm mx-1 hover:variant-filled-primary';
// 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';
string_snippets['classes__events_pres_mgmt_menu__button_warning_special'] = 'btn btn-sm mx-1 variant-glass-warning';
// export string_snippets;

View File

@@ -0,0 +1,731 @@
// Import external files first. Eventually this will be broken up in to smaller files.
import { process_permission_checks } from './ae_utils__perm_checks';
import { iso_datetime_formatter } from './ae_utils__datetime_format';
import { is_datetime_recent } from './ae_utils__is_datetime_recent';
import { format_bytes, guess_file_name, guess_file_extension, get_file_hash } from './ae_utils__files';
type key_str = {
[key: string]: string;
};
type key_val = {
[key: string]: any;
};
/* This utility function will add commas to a number. */
function number_w_commas(x) {
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
/* This utility function looks for any form data with the prefixed name passed and returns a new object.
* This function is used heavily! Be very careful making changes!!!
* If rm_empty_id then it will remove/ignore fields matching. This helps with the API and new records/objects
* If rm_empty then it will remove/ignore fields matching. Sometimes this is needed.
* If trim_values then it will trim string values.
* If bool_tf_str then it will convert string values of true/false (case insensitive) to boolean values.
* Updated 2023-12-22
*/
export let extract_prefixed_form_data = function extract_prefixed_form_data({prefix=null, form_data={}, rm_empty_id=true, rm_empty=false, trim_values=false, bool_tf_str=false, log_lvl=0}) {
if (log_lvl) {
console.log('*** extract_prefixed_form_data() ***');
if (prefix) {
console.log(`Looking for prefixed fields: ${prefix}; Removing emptry ID fields: ${rm_empty_id}; Removing empty fields: ${rm_empty}; Trim string values: ${trim_values}; Convert true/false string values to boolean: ${bool_tf_str}`);
} else {
console.log(`No prefix set. Looking at all fields. Removing emptry ID fields: ${rm_empty_id}; Removing empty fields: ${rm_empty}; Trim string values: ${trim_values}; Convert true/false string values to boolean: ${bool_tf_str}`);
}
}
if (log_lvl > 1) {
console.log('Form Data:');
console.log(form_data);
}
// const data_obj: any = {}; // future TS
let data_obj = {};
for (let field of form_data) {
let [obj_prop_name, obj_prop_value] = field;
if (log_lvl > 1) {
console.log(`${obj_prop_name}: ${obj_prop_value} type=${typeof obj_prop_value}`);
}
// Trim string values if needed
if (trim_values && typeof obj_prop_value === 'string') {
if (log_lvl && obj_prop_value.trim() != obj_prop_value) {
console.log('Trimming string value!');
obj_prop_value = obj_prop_value.trim();
}
}
// Convert string to boolean if needed
if (bool_tf_str && typeof obj_prop_value === 'string') {
// console.log('Flag set for converting true/false string values to boolean!');
if (obj_prop_value.toLowerCase() === 'true') {
if (log_lvl) {
console.log('Converting string to boolean value: true');
}
obj_prop_value = true;
} else if (obj_prop_value.toLowerCase() === 'false') {
if (log_lvl) {
console.log('Converting string to boolean value: false');
}
obj_prop_value = false;
}
}
if (prefix && obj_prop_name.startsWith(prefix)) { // Prefix set
// if (obj_prop_name.startsWith(prefix)) {
obj_prop_name = obj_prop_name.replace(prefix, '');
if (log_lvl) {
console.log(`Checking: (${prefix})${obj_prop_name} value=${obj_prop_value}`);
}
if (rm_empty_id && obj_prop_name.endsWith('id_random') && !obj_prop_value) {
if (log_lvl) {
console.log(`Match but empty *_id_random. Ignoring/removing: ${obj_prop_name}`);
}
} else if (rm_empty && !obj_prop_value) {
if (log_lvl) {
console.log(`Match but empty. Ignoring/removing: ${obj_prop_name}`);
}
} else {
if (log_lvl) {
console.log(`Match: ${prefix})${obj_prop_name} value=${obj_prop_value}`);
}
data_obj[obj_prop_name] = obj_prop_value;
}
} else if (prefix && !obj_prop_name.startsWith(prefix)) { // Prefix set
if (log_lvl > 1) {
console.log('Did not start with prefix. Ignoring');
}
} else { // No prefix set
if (log_lvl) {
console.log(`Checking: ${obj_prop_name} value=${obj_prop_value}`);
}
if (rm_empty_id && obj_prop_name.endsWith('id_random') && !obj_prop_value) {
if (log_lvl > 1) {
console.log(`Match but empty *_id_random. Ignoring/removing: ${obj_prop_name}`);
}
} else if (rm_empty && !obj_prop_value) {
if (log_lvl > 1) {
console.log(`Match but empty. Ignoring/removing: ${obj_prop_name}`);
}
} else {
if (log_lvl > 1) {
console.log(`Match: ${obj_prop_name} value=${obj_prop_value}`);
}
data_obj[obj_prop_name] = obj_prop_value;
}
}
}
if (log_lvl > 1) {
console.log(data_obj);
}
return data_obj;
}
/* This utility function processes specific data string.
* MECARD
* OBJ = OBJ:ot:example,oi:asdf1234
* ot = Aether object type; oi = Aether object ID random
* KV = KV:"key":"value"
* JS = {"id":123,"name":"example name"}
* http or https?
* Common short keys used:
* bdg: Badge ID Random
* reg: Registration ID Random
* exid: External ID
* gn: Given First Name
* fn: Family Last Name
* em: Email Address
*/
// Updated 2022-02-11
export let process_data_string = function process_data_string(data_string: string) {
console.log('*** process_data_string() ***');
// console.log(data_string);
if (!data_string || data_string.length < 1) {
console.log('No data string found.');
return false;
}
let obj: key_val = {};
let colon_index = data_string.indexOf(':')
if (colon_index) {
let data_string_type = data_string.slice(0, colon_index);
console.log(data_string_type);
obj['qr_type'] = data_string_type;
if (data_string_type == 'MECARD') {
let mecard_str = data_string.slice(colon_index+1);
console.log(mecard_str);
obj['str'] = mecard_str;
} else if (data_string_type == 'OBJ') {
let key_value_str = data_string.slice(colon_index+1);
console.log(key_value_str);
let key_value_array = key_value_str.split(',');
// console.log(key_value_array);
let ot_colon_index = key_value_array[0].indexOf(':')
let obj_type = key_value_array[0].slice(ot_colon_index+1);
// console.log(obj_type);
let oi_colon_index = key_value_array[1].indexOf(':')
let obj_id = key_value_array[1].slice(oi_colon_index+1);
// console.log(obj_id);
obj['type'] = obj_type;
obj['id'] = obj_id;
} else if (data_string_type == 'JSON') {
let partial_json_str = data_string.slice(colon_index+1);
console.log(partial_json_str);
let json_str = `{${partial_json_str}}`;
console.log(json_str);
obj['json'] = JSON.parse(json_str);
} else if (data_string_type == 'STR') {
let str = data_string.slice(colon_index+1);
console.log(str);
obj['str'] = str;
} else if (data_string_type == 'http' || data_string_type == 'https') {
console.log(`http or https: ${data_string}`);
obj['type'] = 'url';
obj['url'] = data_string;
} else {
console.log('The unknown data string type was found. Returning the string part.')
let unknown_str = data_string.slice(colon_index+1);
console.log(unknown_str);
obj['str'] = unknown_str;
}
} else {
console.log('The data string type was not found. Returning the entire string.')
console.log(data_string);
obj['qr_type'] = 'UNKNOWN';
obj['str'] = data_string;
// return false;
}
console.log(obj);
return obj; // Returns an object
}
// This function will update the URL and send a message to the parent window (iframe).
// The name should be something like "example_id".
// Svelte specific:
// WARNING: Avoid using `history.pushState(...)` and `history.replaceState(...)` as these will conflict with SvelteKit's router. Use the `pushState` and `replaceState` imports from `$app/navigation` instead.
// Updated 2024-03-02
import { pushState, replaceState } from '$app/navigation';
function handle_url_and_message(name: string, value: null|string) {
console.log(`*** handle_url_and_message() *** name=${name} value=${value}`);
let location = window.location.href;
// console.log('location:', location);
const url = new URL(location);
// console.log('url:', url);
if (value) {
url.searchParams.set(name, value);
history.pushState({}, '', url);
// console.log('url:', url);
// pushState(url.href, {});
// pushState(url.search, {});
// replaceState(url.href, {});
let message = {name: value};
window.parent.postMessage(message, "*");
} else {
url.searchParams.delete(name);
history.pushState({}, '', url);
// console.log('url:', url);
// pushState({}, '', url.search);
// pushState(url.href, {});
// replaceState(url.href, {});
let message = {name: null};
window.parent.postMessage(message, "*");
}
// console.log('Message sent to parent (iframe):', message);
}
function create_a_element({account_id, base_url, hosted_file_id, filename=null, extension=null, text="Download", class_li='text-blue-500'}) {
return `<a href="${base_url}/hosted_file/${hosted_file_id}/download?x_no_account_id_token=${account_id}&filename=${filename}" class="${class_li}">${text}</a>`;
}
function create_img_element({account_id, base_url, hosted_file_id, filename=null, extension=null, class_li='max-w-64', style="", inc_link=false}) {
let img_html = '';
if (filename) {
img_html = `<img src="${base_url}/hosted_file/${hosted_file_id}/download?x_no_account_id_token=${account_id}&filename=${filename}" class="${class_li}" style="${style}" />`;
} else {
img_html = `<img src="${base_url}/hosted_file/${hosted_file_id}/download?x_no_account_id_token=${account_id}" class="${class_li}" style="${style}" />`;
}
if (inc_link) {
let a_html = create_a_element({account_id: account_id, base_url: base_url, hosted_file_id: hosted_file_id, filename: filename, extension: extension});
img_html = `<div class="ae_img ae_a">${img_html}${a_html}</div>`;
}
return img_html;
}
function create_video_element({account_id, base_url, hosted_file_id, filename=null, extension=null, class_li='max-w-64', inc_link=false}) {
let video_html = '';
if (filename) {
video_html = `<video src="${base_url}/hosted_file/${hosted_file_id}/download?x_no_account_id_token=${account_id}&filename=${filename}" controls class="${class_li}"></video>`;
} else {
video_html = `<video src="${base_url}/hosted_file/${hosted_file_id}/download?x_no_account_id_token=${account_id}" controls class="${class_li}"></video>`;
}
if (inc_link) {
let a_html = create_a_element({account_id: account_id, base_url: base_url, hosted_file_id: hosted_file_id, filename: filename, extension: extension});
video_html = `<div class="ae_video ae_a">${video_html}${a_html}</div>`;
}
return video_html;
}
// // Clear the quick access type
// function clear_access_type() {
// // NOTE: I think it makes since to reset this to anonymous even if logged in as an admin or similar.
// window.localStorage.setItem('access_type', 'anonymous');
// // $ae_loc.access_type = null; // 'anonymous';
// $ae_loc.access_type = 'anonymous';
// trigger = 'process_permission_check';
// show_passcode_input = false;
// // $ae_loc = $ae_loc; // Trigger Svelte just in case
// // ae_loc.set($ae_loc);
// // console.log($ae_loc);
// return true;
// }
// This function will take a long string (sentences or paraghraphs) of text and return an estimated number of words.
function count_words(text: string) {
if (!text && text.length < 1) {
return false;
}
let count = text.trim().split(/\s+/).length;
return count;
}
/* Adapted from: To Title Case © 2018 David Gouch | https://github.com/gouch/to-title-case */
// eslint-disable-next-line no-extend-native
function to_title_case (text_string) {
// console.log('*** to_title_case() ***');
let smallWords = /^(a|an|and|as|at|but|by|en|for|if|in|nor|of|on|or|per|the|to|v.?|vs.?|via)$/i
let alphanumericPattern = /([A-Za-z0-9\u00C0-\u00FF])/
let wordSeparators = /([ :–—-])/
return text_string.split(wordSeparators)
.map(function (current, index, array) {
if (
/* Check for small words */
current.search(smallWords) > -1 &&
/* Skip first and last word */
index !== 0 &&
index !== array.length - 1 &&
/* Ignore title end and subtitle start */
array[index - 3] !== ':' &&
array[index + 1] !== ':' &&
/* Ignore small words that start a hyphenated phrase */
(array[index + 1] !== '-' ||
(array[index - 1] === '-' && array[index + 1] === '-'))
) {
return current.toLowerCase()
}
/* Ignore intentional capitalization */
if (current.substr(1).search(/[A-Z]|\../) > -1) {
return current
}
/* Ignore URLs */
if (array[index + 1] === ':' && array[index + 2] !== '') {
return current
}
/* Capitalize the first letter */
return current.replace(alphanumericPattern, function (match) {
return match.toUpperCase()
})
})
.join('')
}
// Updated 2024-06-19
// This function behaves weirdly. It needs to be reviewed and updated.
export let shorten_string = function shorten_string(
{
string,
max_length=45,
begin_length=15,
end_length=5,
wildcard_length=3
}: {
string: undefined|string,
max_length?: number,
begin_length?: number,
end_length?: number,
wildcard_length?: number
}
) {
// console.log('*** shorten_filename() ***');
if (!string || typeof string != 'string') {
// console.log('Invalid string value passed');
// return false;
return '';
}
// NOTE: max_length is not the actual end result length. The actual max will be 45 characters.
// 20 part 1 characters, 5 part 2 characters, 20 part 3 characters
// let length = string.length;
let char_over = string.length-max_length;
let new_string = null;
let wildcards = char_over;
if (char_over > 0) {
let part1 = string.slice(0, begin_length);
let part2 = '';
if (char_over > 5) {
wildcards = 5;
} else {
}
if (wildcard_length) {
part2 = '.'.repeat(wildcard_length);
} else {
part2 = '.'.repeat(wildcards);
}
let part3 = string.slice(end_length*-1);
new_string = part1+part2+part3;
} else {
new_string = string;
}
return new_string;
}
// Updated 2024-06-19
// This function should return a shorted version of a filename if over the max length. It should always contain at least the first character of the original filename and the complete extension.
// Example 1: The Original Long File Name.pdf -> The Orig....pdf
// Example 2: The Original Long File Name.html -> The Ori....html
function shorten_filename(
{
filename,
max_length=20,
slice_end_at=15,
max_end_length=5
}: {
filename: string,
max_length?: number,
slice_end_at?: number,
max_end_length?: number
}
) {
// console.log('*** shorten_filename() ***');
if (typeof filename !== 'string' || filename.length <= max_length) {
return filename;
}
let new_filename = null;
let char_over = filename.length - max_length;
let wildcards = char_over - 4; // The number of characters over the max length
if (wildcards < 1) {
return filename; // No point in changing the filename?
}
let part_1 = filename.slice(0, slice_end_at);
if (wildcards > 3) {
wildcards = 3;
} else {
}
let part_2 = '.'.repeat(wildcards);
let part_3 = filename.slice(max_end_length*-1);
new_filename = part_1+part_2+part_3;
return new_filename;
}
// Updated 2024-6-19
function file_extension_icon(
extension: string
) {
// console.log('*** file_extension_icon() ***');
let file_icons: key_str = {
'file': 'file',
'3gp': 'file-video',
'7z': 'file-archive',
'aac': 'file-audio',
'ac3': 'file-audio',
'aif': 'file-audio',
'aiff': 'file-audio',
'avi': 'file-video',
'bmp': 'file-image',
'csv': 'file-csv',
'doc': 'file-word',
'docx': 'file-word',
'eps': 'file-image',
'flac': 'file-audio',
'gif': 'file-image',
'htm': 'file-code',
'html': 'file-code',
'jpeg': 'file-image',
'jpg': 'file-image',
'key': 'file-powerpoint',
'mkv': 'file-video',
'mov': 'file-video',
'mp3': 'file-audio',
'mp4': 'file-video',
'odp': 'file-powerpoint',
'pdf': 'file-pdf',
'png': 'file-image',
'ppt': 'file-powerpoint',
'pptx': 'file-powerpoint',
'txt': 'file-alt',
'wav': 'file-audio',
'webp': 'file-image',
'xls': 'file-excel',
'xlsx': 'file-excel',
'zip': 'file-archive'
};
if (file_icons[extension]) {
return file_icons[extension];
} else {
// return null;
return file_icons['file'];
}
}
// Updated 2023-08-18
function set_obj_prop_display_name({prop_name, obj_type=null, prefix_w_obj_type=true, prefix_all_w_obj_type=false, replace_underscores=true, title_case=true, override=null}) {
console.log('*** set_obj_prop_display_name() ***');
if (override) {
return override;
}
let known_obj_type_li = ['account', 'address', 'contact', 'event_badge', 'event_exhibit', 'event_file', 'event_location', 'event_person', 'event_presentation', 'event_presenter', 'event_registration', 'event_session', 'event', 'hosted_file', 'order_line', 'order', 'person', 'user'];
let known_obj_type_li_dict = [
{name: 'account', display: 'Account'},
{name: 'address', display: 'Address'},
{name: 'contact', display: 'Contact'},
{name: 'event_badge', display: 'Event Badge'},
{name: 'event_exhibit', display: 'Event Exhibit'},
{name: 'event_file', display: 'Event File'},
{name: 'event_location', display: 'Event Location'},
{name: 'event_person', display: 'Event Person'},
{name: 'event_presentation', display: 'Event Presentation'},
{name: 'event_presenter', display: 'Event Presenter'},
{name: 'event_registration', display: 'Event Registration'},
{name: 'event_session', display: 'Event Session'},
{name: 'event', display: 'Event'},
{name: 'hosted_file', display: 'Hosted File'},
{name: 'order_line', display: 'Order Line'},
{name: 'order', display: 'Order'},
{name: 'person', display: 'Person'},
{name: 'user', display: 'User'},
];
let prop_display_name = prop_name;
if (!prefix_w_obj_type) {
if (obj_type) {
prop_display_name = prop_name.replace(obj_type, '');
} else {
for (let i = 0; i < known_obj_type_li_dict.length; i++) {
// console.log(known_obj_type_li_dict[i]);
if (prop_name.startsWith(known_obj_type_li_dict[i].name)) {
// console.log(`Found ${known_obj_type_li_dict[i].name}`);
prop_display_name = prop_name.replace(known_obj_type_li_dict[i].name, '');
break;
}
}
// for (let i = 0; i < known_obj_type_li.length; i++) {
// // console.log(known_obj_type_li[i]);
// if (prop_name.startsWith(known_obj_type_li[i])) {
// console.log(`Found ${known_obj_type_li[i]}`);
// prop_display_name = prop_name.replace(known_obj_type_li[i], '');
// break;
// }
// }
}
} else {
if (!prefix_all_w_obj_type) {
for (let i = 0; i < known_obj_type_li.length; i++) {
// console.log(known_obj_type_li[i]);
let found_obj_type = null;
if (prop_name.startsWith(known_obj_type_li_dict[i].name)) {
// if (prop_name.startsWith(known_obj_type_li[i])) {
// console.log(`Found ${known_obj_type_li_dict[i].name}`);
found_obj_type = known_obj_type_li_dict[i].name;
if (found_obj_type == obj_type) {
prop_display_name = prop_name.replace(known_obj_type_li_dict[i].name, '');
}
break;
}
}
// if (obj_type) {
// prop_display_name = prop_name.replace(obj_type, '');
// } else {
}
}
// console.log(prop_display_name);
if (prop_display_name.search('ID')) {
}
prop_display_name = prop_display_name.replace('id_random', 'ID');
if (replace_underscores) {
prop_display_name = prop_display_name.replaceAll('_', ' ');
}
if (title_case) {
prop_display_name = to_title_case(prop_display_name);
}
// console.log(prop_display_name);
return prop_display_name;
}
function return_obj_type_path({obj_type=null, obj_type_prop_name=null}) {
console.log('*** set_obj_prop_display_name() ***');
let obj_type_path = null;
let known_obj_type_li = ['account', 'address', 'archive', 'archive_content', 'contact', 'event_badge', 'event_exhibit', 'event_file', 'event_location', 'event_person', 'event_presentation', 'event_presenter', 'event_registration', 'event_session', 'event', 'hosted_file', 'order_line', 'order', 'person', 'post', 'post_comment', 'user'];
let known_obj_type_li_dict = [
{name: 'account', display: 'Account', path: 'account'},
{name: 'archive', display: 'Archive', path: 'archive'},
{name: 'address', display: 'Address', path: 'address'},
{name: 'archive', display: 'Archive', path: 'archive'},
{name: 'archive_content', display: 'Archive Content', path: 'archive/content'},
{name: 'contact', display: 'Contact', path: 'contact'},
{name: 'data_store', display: 'Data Store', path: 'data_store'},
{name: 'event_abstract', display: 'Event Abstract', path: 'event/abstract'},
{name: 'event_badge', display: 'Event Badge', path: 'event/badge'},
{name: 'event_device', display: 'Event Device', path: 'event/device'},
{name: 'event_exhibit', display: 'Event Exhibit', path: 'event/exhibit'},
{name: 'event_file', display: 'Event File', path: 'event/file'},
{name: 'event_location', display: 'Event Location', path: 'event/location'},
{name: 'event_person', display: 'Event Person', path: 'event/person'},
{name: 'event_presentation', display: 'Event Presentation', path: 'event/'},
{name: 'event_presenter', display: 'Event Presenter', path: 'event/presenter'},
{name: 'event_registration', display: 'Event Registration', path: 'event/registration'},
{name: 'event_session', display: 'Event Session', path: 'event/session'},
{name: 'event', display: 'Event', path: 'event'},
{name: 'hosted_file', display: 'Hosted File', path: 'hosted_file'},
{name: 'journal', display: 'Journal', path: 'journal'},
{name: 'journal_entry', display: 'Journal Entry', path: 'journal/entry'},
{name: 'order_line', display: 'Order Line', path: 'order/line'},
{name: 'order', display: 'Order', path: 'order'},
{name: 'person', display: 'Person', path: 'person'},
{name: 'post', display: 'Archive', path: 'post'},
{name: 'post_comment', display: 'Archive Content', path: 'post/comment'},
{name: 'user', display: 'User', path: 'user'},
];
if (obj_type) {
// Need to loop through known for safety?
obj_type_path = obj_type_prop_name.replaceAll('_', '/');
} else if (obj_type_prop_name) {
let found_obj_type_name = null;
let found_obj_type_path = null;
for (let i = 0; i < known_obj_type_li_dict.length; i++) {
// console.log(known_obj_type_li_dict[i]);
// let guessed_obj_type = prop_name.startsWith(known_obj_type_li_dict[i]
if (obj_type_prop_name.startsWith(known_obj_type_li_dict[i].name)) {
console.log(`Found ${known_obj_type_li_dict[i].name}`);
found_obj_type_name = known_obj_type_li_dict[i].name;
found_obj_type_path = known_obj_type_li_dict[i].path;
// obj_type_path = obj_type_prop_name.replaceAll('_', '/');
obj_type_path = found_obj_type_path;
break;
}
}
} else {
console.log('Missing required parameters');
return false;
}
return obj_type_path;
}
export let ae_util = {
is_datetime_recent: is_datetime_recent,
process_permission_checks: process_permission_checks,
iso_datetime_formatter: iso_datetime_formatter,
format_bytes: format_bytes,
number_w_commas: number_w_commas,
guess_file_name: guess_file_name,
guess_file_extension: guess_file_extension,
get_file_hash: get_file_hash,
extract_prefixed_form_data: extract_prefixed_form_data,
process_data_string: process_data_string,
handle_url_and_message: handle_url_and_message,
create_a_element: create_a_element,
create_img_element: create_img_element,
create_video_element: create_video_element,
count_words: count_words,
to_title_case: to_title_case,
shorten_string: shorten_string,
shorten_filename: shorten_filename,
file_extension_icon: file_extension_icon,
set_obj_prop_display_name: set_obj_prop_display_name,
return_obj_type_path: return_obj_type_path,
};

View File

@@ -0,0 +1,153 @@
import dayjs from 'dayjs';
export let iso_datetime_formatter = function iso_datetime_formatter(
raw_datetime: null|string|Date = null,
named_format: string = 'datetime_iso_no_seconds', // date_iso, datetime_iso_no_seconds
time_24_hours: boolean = false
) {
// console.log('*** iso_datetime_formatter() ***');
// https://en.wikipedia.org/wiki/ISO_8601
// https://day.js.org/docs/en/display/format
// ISO 8601-1:2019 includes the T before the time portion
// ISO 8601-1:2019 midnight may only be referred to as "00:00", corresponding to the beginning of a calendar day
// and "24:00" is no longer allowed corresponding to the end of a day
// 60 is only used to denote an added leap second
// ISO 8601 UTC: 2021-03-04T19:04:44+00:00
// ISO 8601 UTC: 2021-03-04T19:04:44Z
// ISO 8601 UTC: 20210304T190444Z
// datetime_iso 'YYYY-MM-DD HH:mm:ss'
// datetime_iso_12 'YYYY-MM-DD hh:mm:ss A'
// datetime_iso_12_short 'YY-MM-DD hh:mm A'
// datetime_iso_tz 'YYYY-MM-DD HH:mm:ss'
// datetime_12_no_seconds 'YYYY-MM-DD hh:mm A'
// datetime_long 'dddd, MMMM D, YYYY hh:mm:ss A'
// datetime_medium 'ddd, MMM D, YYYY hh:mm:ss A'
// datetime_short 'MMM D, YY hh:mm A'
// date_iso 'YYYY-MM-DD'
// date_long 'dddd, MMMM D, YYYY'
// date_medium 'ddd, MMM D, YYYY'
// date_short 'MMM D, YY'
// time_iso 'HH:mm:ss'
// time_iso_12 'hh:mm:ss A'
// time_long 'hh:mm:ss A'
// time_medium 'h:m:s A'
// time_short 'hh:mm A'
// dayjs(raw_datetime).format('dddd, MMMM D, YYYY hh:mm:ss A');
if (!raw_datetime) {
raw_datetime = new Date(); // Get the current datetime if one was not passed.
}
let datetime_string = null;
switch (named_format) {
case 'datetime_iso':
datetime_string = dayjs(raw_datetime).format('YYYY-MM-DD HH:mm:ss');
break;
case 'datetime_iso_no_seconds':
datetime_string = dayjs(raw_datetime).format('YYYY-MM-DD HH:mm');
break;
case 'datetime_iso_12_short':
datetime_string = dayjs(raw_datetime).format('YY-MM-DD hh:mm A');
break;
case 'datetime_iso_12_short_month':
datetime_string = dayjs(raw_datetime).format('MM-DD hh:mm A');
break;
case 'datetime_12_no_seconds':
datetime_string = dayjs(raw_datetime).format('YYYY-MM-DD hh:mm A');
break;
case 'datetime_short':
datetime_string = dayjs(raw_datetime).format('MMM D, YY HH:mm');
break;
case 'datetime_12_short':
datetime_string = dayjs(raw_datetime).format('MMM D, YY hh:mm A');
break;
case 'datetime_medium':
datetime_string = dayjs(raw_datetime).format('MMM D, YYYY H:mm');
break;
case 'datetime_12_medium':
datetime_string = dayjs(raw_datetime).format('MMM D, YYYY h:mm A');
break;
case 'datetime_long':
datetime_string = dayjs(raw_datetime).format('MMMM D, YYYY HH:mm');
break;
case 'datetime_12_long':
datetime_string = dayjs(raw_datetime).format('MMMM D, YYYY hh:mm A');
break;
case 'datetime_short_month':
datetime_string = dayjs(raw_datetime).format('MMM D hh:mm A');
break;
case 'datetime_long_month':
datetime_string = dayjs(raw_datetime).format('MMMM D hh:mm A');
break;
case 'datetime_short_day':
datetime_string = dayjs(raw_datetime).format('D hh:mm A');
break;
case 'date_iso':
datetime_string = dayjs(raw_datetime).format('YYYY-MM-DD');
break;
case 'date_long_month_day':
datetime_string = dayjs(raw_datetime).format('MMMM D');
break;
case 'date_short':
datetime_string = dayjs(raw_datetime).format('MMM D, YY');
break;
case 'date_short_no_year':
datetime_string = dayjs(raw_datetime).format('MMM D');
break;
case 'date_long':
datetime_string = dayjs(raw_datetime).format('MMMM D, YYYY');
break;
case 'date_full':
datetime_string = dayjs(raw_datetime).format('dddd, MMMM D, YYYY');
break;
case 'date_full_no_year':
datetime_string = dayjs(raw_datetime).format('dddd, MMMM D');
break;
case 'time_iso':
datetime_string = dayjs(raw_datetime).format('HH:mm:ss');
break;
case 'time_long':
datetime_string = dayjs(raw_datetime).format('HH:mm:ss A');
break;
case 'time_12_long':
datetime_string = dayjs(raw_datetime).format('hh:mm:ss A');
break;
case 'time_short':
datetime_string = dayjs(raw_datetime).format('HH:mm');
break;
case 'time_short_no_leading':
datetime_string = dayjs(raw_datetime).format('H:mm');
break;
case 'time_12_short':
datetime_string = dayjs(raw_datetime).format('hh:mm A');
break;
case 'time_12_short_no_leading':
datetime_string = dayjs(raw_datetime).format('h:mm A');
break;
case 'week_long':
datetime_string = dayjs(raw_datetime).format('dddd');
break;
case 'week_medium':
datetime_string = dayjs(raw_datetime).format('ddd');
break;
case 'week_short':
datetime_string = dayjs(raw_datetime).format('dd');
break;
default:
// console.log(`The named format passed (${named_format}) did not match a common name. Trying to format with the named format value.`);
datetime_string = dayjs(raw_datetime).format(named_format);
// datetime_string = dayjs(raw_datetime).format('YYYY-MM-DD HH:mm:ss');
}
return datetime_string;
}

View File

@@ -0,0 +1,72 @@
// These are all file related functions.
export let format_bytes = function format_bytes(
bytes: number,
decimals: number = 2
) {
if (bytes === 0) return '0 Bytes';
const k = 1024;
const dm = decimals < 0 ? 0 : decimals;
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
}
// Updated 2024-08-12
export let guess_file_name = function guess_file_name(filename_string: string) {
// console.log('*** guess_file_name() ***');
if (!filename_string) {
return '';
}
if (filename_string.includes('.')) {
let file_name = filename_string.substring(0, filename_string.lastIndexOf('.'));
// console.log(file_name);
return file_name;
} else {
return filename_string;
}
}
// Updated 2024-08-12
export let guess_file_extension = function guess_file_extension(filename_string: string) {
// console.log('*** guess_file_extension() ***');
if (!filename_string) {
return '';
}
if (!filename_string.includes('.')) {
return '';
}
let file_extension = filename_string.substring(filename_string.lastIndexOf('.') + 1, filename_string.length) || filename_string;
// console.log(file_extension);
return file_extension;
}
// Updated 2024-08-12
export let get_file_hash = async function get_file_hash(file) {
return new Promise((resolve, reject) => {
let file_reader = new FileReader();
file_reader.onload = async function() {
if (file_reader.result.byteLength !== file.size) {
console.log('File was not read completely');
reject("Error reading the file");
}
const hash_buffer = await crypto.subtle.digest('SHA-256', file_reader.result);
const hash_array = Array.from(new Uint8Array(hash_buffer));
const hash_hex = hash_array.map(b => b.toString(16).padStart(2, '0')).join('');
resolve(hash_hex);
};
file_reader.readAsArrayBuffer(file);
});
}

View File

@@ -0,0 +1,23 @@
// Function to check if the file (or anything) timestamp was created within the last X minutes
export let is_datetime_recent = function is_datetime_recent(
{
datetime,
minutes
}: {
datetime: string,
minutes: number
}) {
console.log(`*** is_datetime_recent() *** datetime=${datetime} minutes=${minutes}`);
let now: any = new Date();
let then: any = new Date(datetime);
let diff = now - then;
let diff_minutes = Math.floor(diff / 60000);
if (diff_minutes < minutes) {
return true;
} else {
return false;
}
}

View File

@@ -0,0 +1,199 @@
type key_val = {
[key: string]: any;
};
// NOTE: I know there is a better more efficient way to do this, but I don't have time for that right now.
export let process_permission_checks = function process_permission_checks(access_type: string) {
// let access_checks = { 'access_type': null, 'super_check': null };
let access_checks: key_val = {};
if (access_type == 'super') {
access_checks.allow_access = true;
access_checks.access_type = 'super';
access_checks.super_check = true;
access_checks.manager_check = false;
access_checks.administrator_check = false;
access_checks.support_check = false;
access_checks.assistant_check = false;
access_checks.trusted_check = false;
access_checks.verified_check = false;
access_checks.provisional_check = false;
access_checks.public_check = false;
access_checks.authenticated_check = true;
access_checks.anonymous_check = false;
access_checks.super_access = true;
access_checks.manager_access = true;
access_checks.administrator_access = true;
access_checks.support_access = true;
access_checks.assistant_access = true;
access_checks.trusted_access = true;
access_checks.verified_access = true;
access_checks.provisional_access = true;
access_checks.public_access = true;
access_checks.authenticated_access = true;
access_checks.anonymous_access = true;
} else if (access_type == 'manager') {
access_checks.allow_access = true;
access_checks.access_type = 'manager';
access_checks.super_check = false;
access_checks.manager_check = true;
access_checks.administrator_check = false;
access_checks.support_check = false;
access_checks.assistant_check = false;
access_checks.trusted_check = false;
access_checks.verified_check = false;
access_checks.provisional_check = false;
access_checks.public_check = false;
access_checks.authenticated_check = true;
access_checks.anonymous_check = false;
access_checks.super_access = false;
access_checks.manager_access = true;
access_checks.administrator_access = true;
access_checks.support_access = true;
access_checks.assistant_access = true;
access_checks.trusted_access = true;
access_checks.verified_access = true;
access_checks.provisional_access = true;
access_checks.public_access = true;
access_checks.authenticated_access = true;
access_checks.anonymous_access = true;
} else if (access_type == 'administrator') {
access_checks.allow_access = true;
access_checks.access_type = 'administrator';
access_checks.super_check = false;
access_checks.manager_check = false;
access_checks.administrator_check = true;
access_checks.support_check = false;
access_checks.assistant_check = false;
access_checks.trusted_check = false;
access_checks.verified_check = false;
access_checks.provisional_check = false;
access_checks.public_check = false;
access_checks.authenticated_check = false;
access_checks.anonymous_check = false;
access_checks.super_access = false;
access_checks.manager_access = false;
access_checks.administrator_access = true;
access_checks.support_access = true;
access_checks.assistant_access = true;
access_checks.trusted_access = true;
access_checks.verified_access = true;
access_checks.provisional_access = true;
access_checks.public_access = true;
access_checks.authenticated_access = true;
access_checks.anonymous_access = true;
} else if (access_type == 'trusted') {
access_checks.allow_access = true; // Should this be true?? -2024-10-03
access_checks.access_type = 'trusted';
access_checks.super_check = false;
access_checks.manager_check = false;
access_checks.administrator_check = false;
access_checks.support_check = false;
access_checks.assistant_check = false;
access_checks.trusted_check = true;
access_checks.verified_check = false;
access_checks.provisional_check = false;
access_checks.public_check = false;
access_checks.authenticated_check = true;
access_checks.anonymous_check = false;
access_checks.super_access = false;
access_checks.manager_access = false;
access_checks.administrator_access = false;
access_checks.support_access = false;
access_checks.assistant_access = false;
access_checks.trusted_access = true;
access_checks.verified_access = true;
access_checks.provisional_access = true;
access_checks.public_access = true;
access_checks.authenticated_access = true;
access_checks.anonymous_access = true;
} else if (access_type == 'public') {
access_checks.access_type = 'public';
access_checks.super_check = false;
access_checks.manager_check = false;
access_checks.administrator_check = false;
access_checks.support_check = false;
access_checks.assistant_check = false;
access_checks.trusted_check = false;
access_checks.verified_check = false;
access_checks.provisional_check = false;
access_checks.public_check = true;
access_checks.authenticated_check = false;
access_checks.anonymous_check = false;
access_checks.super_access = false;
access_checks.manager_access = false;
access_checks.administrator_access = false;
access_checks.support_access = false;
access_checks.assistant_access = false;
access_checks.trusted_access = false;
access_checks.verified_access = false;
access_checks.provisional_access = false;
access_checks.public_access = true;
access_checks.authenticated_access = true;
access_checks.anonymous_access = true;
} else if (access_type == 'authenticated') {
access_checks.access_type = 'authenticated';
access_checks.super_check = false;
access_checks.manager_check = false;
access_checks.administrator_check = false;
access_checks.support_check = false;
access_checks.assistant_check = false;
access_checks.trusted_check = false;
access_checks.verified_check = false;
access_checks.provisional_check = false;
access_checks.public_check = false;
access_checks.authenticated_check = true;
access_checks.anonymous_check = false;
access_checks.super_access = false;
access_checks.manager_access = false;
access_checks.administrator_access = false;
access_checks.support_access = false;
access_checks.assistant_access = false;
access_checks.trusted_access = false;
access_checks.verified_access = false;
access_checks.provisional_access = false;
access_checks.public_access = false;
access_checks.authenticated_access = true;
access_checks.anonymous_access = true;
} else {
access_checks.access_type = 'anonymous';
access_checks.super_check = false;
access_checks.manager_check = false;
access_checks.administrator_check = false;
access_checks.support_check = false;
access_checks.assistant_check = false;
access_checks.trusted_check = false;
access_checks.verified_check = false;
access_checks.provisional_check = false;
access_checks.public_check = false;
access_checks.authenticated_check = false;
access_checks.anonymous_check = true;
access_checks.super_access = false;
access_checks.manager_access = false;
access_checks.administrator_access = false;
access_checks.support_access = false;
access_checks.assistant_access = false;
access_checks.trusted_access = false;
access_checks.verified_access = false;
access_checks.provisional_access = false;
access_checks.public_access = false;
access_checks.authenticated_access = false;
access_checks.anonymous_access = true;
}
return access_checks;
}

39
src/lib/analytics.svelte Normal file
View File

@@ -0,0 +1,39 @@
<script lang="ts">
// import { page } from '$app/stores'
export let site_google_tracking_id: string = '';
console.log(`site_google_tracking_id = `, site_google_tracking_id);
if (typeof window !== 'undefined') {
window.dataLayer = window.dataLayer || [];
window.gtag = function gtag(): void {
window.dataLayer.push(arguments);
};
window.gtag('js', new Date());
window.gtag('config', site_google_tracking_id);
}
// $: if (typeof gtag !== 'undefined') {
// gtag('config', site_google_tracking_id, {
// page_title: document.title,
// page_path: $page.url.pathname,
// })
// }
</script>
<svelte:head>
<script
async
src="https://www.googletagmanager.com/gtag/js?id={site_google_tracking_id}">
</script>
<!-- <script>
window.dataLayer = window.dataLayer || []
function gtag() {
dataLayer.push(arguments)
}
gtag('js', new Date())
gtag('config', site_google_tracking_id)
</script> -->
</svelte:head>

913
src/lib/api.ts Normal file
View File

@@ -0,0 +1,913 @@
// Aether API Library (TS)
// This is intended to be used with the Aether API. The goal is to just import all of the core functions and re-export them as a single module. This is to make it easier to import the functions into other modules.
// This needs to be cleaned up and ideally removed the need for Axios.
import type { key_val } from '$lib/ae_stores';
import { delete_object } from './ae_api/api_delete_object'; // Exported at the end of this file
import { get_object } from './ae_api/api_get_object'; // Exported at the end of this file
import { patch_object } from './ae_api/api_patch_object'; // Exported at the end of this file
import { post_object } from './ae_api/api_post_object'; // Exported at the end of this file
import { get_ae_obj_id_crud } from '$lib/ae_api/api_get__crud_obj_id';
import { get_ae_obj_li_for_obj_id_crud } from '$lib/ae_api/api_get__crud_obj_li_v1';
import { get_ae_obj_li_for_obj_id_crud_v2 } from '$lib/ae_api/api_get__crud_obj_li_v2';
// This new function has not been tested yet!!!
// Updated 2024-08-07
export let get_ae_obj_li_for_lu = async function get_ae_obj_li_for_lu(
{
api_cfg,
// obj_type,
for_lu_type,
// for_obj_id=null,
// use_alt_table=false,
// use_alt_base=false,
// inc={},
enabled='enabled',
hidden='not_hidden',
order_by_li=null,
limit=999999,
offset=0,
// key,
// jwt=null,
headers={},
params_json=null,
// json_obj=null,
params={},
return_meta=false,
log_lvl=1
}: {
api_cfg: any,
// obj_type: string,
for_lu_type: string,
// for_lu_id?: string,
// use_alt_table?: boolean,
// use_alt_base?: boolean,
// inc?: key_val
enabled?: string,
hidden?: string,
order_by_li?: any,
limit?: number,
offset?: number,
// key: string,
// jwt?: string,
headers?: any,
params_json?: any,
// json_obj?: any,
params?: key_val,
return_meta?: boolean,
log_lvl?: number
}
) {
if (log_lvl) {
console.log(`*** get_ae_obj_li_for_lu() *** for_lu_type=${for_lu_type}`);
}
let endpoint = '';
if (for_lu_type == 'country_subdivision') {
endpoint = `/crud/lu/country_subdivision/list`;
} else if (for_lu_type == 'country') {
endpoint = `/crud/lu/country/list`;
} else if (for_lu_type == 'time_zone') {
endpoint = `/crud/lu/time_zone/list`;
} else {
console.log(`Unknown object type: ${for_lu_type}`);
return false;
}
if (log_lvl) {
console.log('Endpoint:', endpoint);
}
if (order_by_li) {
headers['order_by_li'] = order_by_li;
}
let allowed_enabled_list = ['all', 'enabled', 'not_enabled']
if (allowed_enabled_list.includes(enabled) ) {
params['enabled'] = enabled;
}
let allowed_hidden_list = ['all', 'hidden', 'not_hidden'];
if (allowed_hidden_list.includes(hidden) ) {
params['hidden'] = hidden;
}
if (limit >= 0) {
params['limit'] = limit;
}
if (offset >= 0) {
params['offset'] = offset;
}
let object_li_get_promise = await api.get_object({
api_cfg: api_cfg,
endpoint: endpoint,
headers: headers,
params: params,
return_meta: return_meta,
log_lvl: log_lvl
});
if (log_lvl > 1) {
console.log(object_li_get_promise);
}
return object_li_get_promise;
}
// Updated 2023-07-24
export let create_ae_obj_crud = async function create_ae_obj_crud(
{
api_cfg,
obj_type,
field_name = null,
field_value = null,
fields = {},
key,
jwt = null,
headers = {},
params = {},
data = {},
return_obj = false,
obj_v_name = '',
return_meta = false,
log_lvl = 0
} : {
api_cfg: any,
obj_type: string,
field_name?: null|string,
field_value?: any,
fields?: key_val,
key: string,
jwt?: null|string,
headers?: key_val,
params?: key_val,
data?: key_val,
return_obj?: boolean,
obj_v_name?: string,
return_meta?: boolean,
log_lvl?: number
}
) {
if (log_lvl) {
console.log(`*** create_ae_obj_crud() *** obj_type=${obj_type}`);
}
data['super_key'] = key;
data['jwt'] = jwt;
// NOTE: The key and or JWT should be in the header of the DELETE, GET, PATCH, POST
// This obj_v_name is the view name to use when returning data. Do not prefix it with v_. This is checked and done automatically by the API.
// This is not currently being exposed to other areas of the code. It is only used here. For now?
if (obj_v_name) {
obj_v_name = '';
}
let endpoint = '';
if (obj_type == 'account') {
endpoint = `/crud/account`;
} else if (obj_type == 'address') {
endpoint = `/crud/address`;
} else if (obj_type == 'archive') {
endpoint = `/crud/archive`;
} else if (obj_type == 'archive_content') {
endpoint = `/crud/archive/content`;
} else if (obj_type == 'contact') {
endpoint = `/crud/contact`;
} else if (obj_type == 'data_store') {
endpoint = `/crud/data_store`;
} else if (obj_type == 'event') {
endpoint = `/crud/event`;
} else if (obj_type == 'event_abstract') {
endpoint = `/crud/event/abstract`;
} else if (obj_type == 'event_badge') {
endpoint = `/crud/event/badge`;
} else if (obj_type == 'event_device') {
endpoint = `/crud/event/device`;
} else if (obj_type == 'event_exhibit') {
endpoint = `/crud/event/exhibit`;
} else if (obj_type == 'event_exhibit_tracking') {
endpoint = `/crud/event/exhibit/tracking`;
} else if (obj_type == 'event_file') {
endpoint = `/crud/event/file`;
} else if (obj_type == 'event_location') {
endpoint = `/crud/event/location`;
} else if (obj_type == 'event_person') {
endpoint = `/crud/event/person`;
} else if (obj_type == 'event_presentation') {
endpoint = `/crud/event/presentation`;
} else if (obj_type == 'event_presenter') {
endpoint = `/crud/event/presenter`;
// obj_v_name = 'event_presenter_soft_links';
} else if (obj_type == 'event_session') {
endpoint = `/crud/event/session`;
} else if (obj_type == 'event_track') {
endpoint = `/crud/event/track`;
} else if (obj_type == 'grant') {
endpoint = `/crud/grant`;
} else if (obj_type == 'hosted_file') {
endpoint = `/crud/hosted_file`;
} else if (obj_type == 'journal') {
endpoint = `/crud/journal`;
} else if (obj_type == 'journal_entry') {
endpoint = `/crud/journal/entry`;
} else if (obj_type == 'order') {
endpoint = `/crud/order`;
} else if (obj_type == 'order_line') {
endpoint = `/crud/order/line`;
} else if (obj_type == 'page') {
endpoint = `/crud/page`;
} else if (obj_type == 'person') {
endpoint = `/crud/person`;
} else if (obj_type == 'post') {
endpoint = `/crud/post`;
} else if (obj_type == 'post_comment') {
endpoint = `/crud/post/comment`;
} else if (obj_type == 'sponsorship_cfg') {
endpoint = `/crud/sponsorship/cfg`;
} else if (obj_type == 'sponsorship') {
endpoint = `/crud/sponsorship`;
} else if (obj_type == 'site') {
endpoint = `/crud/site`;
// } else if (obj_type == 'user') {
// endpoint = `/crud/user`;
} else {
console.log(`Unknown object type: ${obj_type}`);
return false;
}
if (log_lvl) {
console.log('Endpoint:', endpoint);
}
if (return_obj) {
params['return_obj'] = true;
// Pass along the view name to use for returning data.
if (obj_v_name) {
params['obj_v_name'] = obj_v_name;
}
} else {
params['return_obj'] = false; // NOTE: This is needed because the current default on the API is to return the object.
}
if (field_name) {
data['data_list'] = {}; // Really an object/dict
data['data_list'][field_name] = field_value;
// data['data_list']['testing'] = 'asdf 1234';
} else if (fields) {
data['data_list'] = fields; // Really an object/dict
}
// NOTE: The data object may contain objects that need to be converted to JSON strings. This is done by adding "_json" to the end of the property name. This is done because the API does not support nested objects. This is a limitation of the API.
if (data['data_list']) {
if (log_lvl > 1) {
console.log('Data List:', data['data_list']);
}
for (const [key, value] of Object.entries(data['data_list'])) {
// console.log(key, value);
if (key.endsWith('_json')) {
if (log_lvl) {
console.log(`${key}: ${value}`);
}
data['data_list'][key] = JSON.stringify(value);
}
}
}
if (log_lvl) {
console.log('Data:', data);
}
// params['xxxxx run_safety_check xxxxx'] = false;
params['by_alias'] = false;
if (log_lvl) {
console.log('Params:', params);
}
let object_obj_post_promise = await post_object({api_cfg: api_cfg, endpoint: endpoint, params: params, data: data, log_lvl: log_lvl});
if (log_lvl > 1) {
console.log(object_obj_post_promise);
}
return object_obj_post_promise;
}
// Updated 2023-06-28
export let update_ae_obj_id_crud = async function update_ae_obj_id_crud(
{
api_cfg,
obj_type,
obj_id,
field_name,
field_value,
fields = {},
key,
jwt = null,
headers = {},
params = {},
data = {},
return_obj = false,
obj_v_name = '',
return_meta = false,
log_lvl = 3
}: {
api_cfg: any,
obj_type: string,
obj_id: string,
field_name?: string,
field_value?: any,
fields?: key_val,
key: string,
jwt?: null|string,
headers?: key_val,
params?: key_val,
data?: null|key_val,
return_obj?: boolean,
obj_v_name?: string,
return_meta?: boolean,
log_lvl?: number
}
) {
if (log_lvl) {
console.log('*** update_ae_obj_id_crud() ***');
}
if (!data) {
data = {};
}
data['super_key'] = key;
data['jwt'] = jwt;
// NOTE: The key and or JWT should be in the header of the DELETE, GET, PATCH, POST
// This obj_v_name is the view name to use when returning data. Do not prefix it with v_. This is checked and done automatically by the API.
// This is not currently being exposed to other areas of the code. It is only used here. For now?
if (obj_v_name) {
obj_v_name = '';
}
let endpoint = '';
if (obj_type == 'account') {
endpoint = `/crud/account/${obj_id}`;
} else if (obj_type == 'address') {
endpoint = `/crud/address/${obj_id}`;
} else if (obj_type == 'archive') {
endpoint = `/crud/archive/${obj_id}`;
} else if (obj_type == 'archive_content') {
endpoint = `/crud/archive/content/${obj_id}`;
} else if (obj_type == 'contact') {
endpoint = `/crud/contact/${obj_id}`;
} else if (obj_type == 'data_store') {
endpoint = `/crud/data_store/${obj_id}`;
} else if (obj_type == 'event') {
endpoint = `/crud/event/${obj_id}`;
} else if (obj_type == 'event_abstract') {
endpoint = `/crud/event/abstract/${obj_id}`;
} else if (obj_type == 'event_badge') {
endpoint = `/crud/event/badge/${obj_id}`;
} else if (obj_type == 'event_device') {
endpoint = `/crud/event/device/${obj_id}`;
} else if (obj_type == 'event_exhibit') {
endpoint = `/crud/event/exhibit/${obj_id}`;
} else if (obj_type == 'event_exhibit_tracking') {
endpoint = `/crud/event/exhibit/tracking/${obj_id}`;
} else if (obj_type == 'event_file') {
endpoint = `/crud/event/file/${obj_id}`;
} else if (obj_type == 'event_location') {
endpoint = `/crud/event/location/${obj_id}`;
} else if (obj_type == 'event_person') {
endpoint = `/crud/event/person/${obj_id}`;
} else if (obj_type == 'event_presentation') {
endpoint = `/crud/event/presentation/${obj_id}`;
} else if (obj_type == 'event_presenter') {
endpoint = `/crud/event/presenter/${obj_id}`;
// obj_v_name = 'event_presenter_soft_links';
} else if (obj_type == 'event_session') {
endpoint = `/crud/event/session/${obj_id}`;
} else if (obj_type == 'event_track') {
endpoint = `/crud/event/track/${obj_id}`;
} else if (obj_type == 'grant') {
endpoint = `/crud/grant/${obj_id}`;
} else if (obj_type == 'hosted_file') {
endpoint = `/crud/hosted_file/${obj_id}`;
} else if (obj_type == 'journal') {
endpoint = `/crud/journal/${obj_id}`;
} else if (obj_type == 'journal_entry') {
endpoint = `/crud/journal/entry/${obj_id}`;
} else if (obj_type == 'order') {
endpoint = `/crud/order/${obj_id}`;
} else if (obj_type == 'order_line') {
endpoint = `/crud/order/line/${obj_id}`;
} else if (obj_type == 'page') {
endpoint = `/crud/page/${obj_id}`;
} else if (obj_type == 'person') {
endpoint = `/crud/person/${obj_id}`;
} else if (obj_type == 'post') {
endpoint = `/crud/post/${obj_id}`;
} else if (obj_type == 'post_comment') {
endpoint = `/crud/post/comment/${obj_id}`;
} else if (obj_type == 'site') {
endpoint = `/crud/site/${obj_id}`;
} else if (obj_type == 'sponsorship_cfg') {
endpoint = `/crud/sponsorship/cfg/${obj_id}`;
} else if (obj_type == 'sponsorship') {
endpoint = `/crud/sponsorship/${obj_id}`;
// } else if (obj_type == 'user') {
// endpoint = `/crud/user/${obj_id}`;
} else {
console.log(`Unknown object type: ${obj_type}`);
return false;
}
if (log_lvl) {
console.log('Endpoint:', endpoint);
}
if (return_obj) {
params['return_obj'] = true;
// Pass along the view name to use for returning data.
if (obj_v_name) {
params['obj_v_name'] = obj_v_name;
}
} else {
params['return_obj'] = false; // NOTE: This is needed because the current default on the API is to return the object.
}
if (field_name) {
data['data_list'] = {}; // Really an object/dict
data['data_list'][field_name] = field_value;
// data['data_list']['testing'] = 'asdf 1234';
} else if (fields) {
data['data_list'] = fields; // Really an object/dict
}
// NOTE: The data object may contain objects that need to be converted to JSON strings. This is done by adding "_json" to the end of the property name. This is done because the API does not support nested objects. This is a limitation of the API.
if (data['data_list']) {
if (log_lvl > 1) {
console.log('Data List:', data['data_list']);
}
for (const [key, value] of Object.entries(data['data_list'])) {
// console.log(key, value);
if (key.endsWith('_json')) {
if (log_lvl) {
console.log(`${key}: ${value}`);
}
data['data_list'][key] = JSON.stringify(value);
}
}
}
// If the data is an object then we need to loop through the object and convert any objects to JSON strings, but only if the property name ends with "_json".
// if (Array.isArray(data)) {
// // console.log('Data is an array');
// for (let i = 0; i < data.length; i++) {
// // console.log(data[i]);
// if (typeof data[i] == 'object') {
// // console.log('Data is an object');
// for (const [key, value] of Object.entries(data[i])) {
// // console.log(key, value);
// if (key.endsWith('_json')) {
// console.log(`${key}: ${value}`);
// data[i][key] = JSON.stringify(value);
// }
// }
// }
// }
// } else if (typeof data == 'object') {
// // console.log('Data is an object');
// for (const [key, value] of Object.entries(data)) {
// // console.log(key, value);
// if (key.endsWith('_json')) {
// console.log(`${key}: ${value}`);
// data[key] = JSON.stringify(value);
// }
// }
// }
if (log_lvl) {
console.log('Data:', data);
}
// params['xxxxx run_safety_check xxxxx'] = false;
params['by_alias'] = false;
if (log_lvl) {
console.log('Params:', params);
}
let object_obj_patch_promise = await patch_object({api_cfg: api_cfg, endpoint: endpoint, params: params, data: data, log_lvl: log_lvl});
if (log_lvl > 1) {
console.log(object_obj_patch_promise);
}
return object_obj_patch_promise;
}
// Updated 2023-11-14
export let delete_ae_obj_id_crud = async function delete_ae_obj_id_crud(
{
api_cfg,
obj_type,
obj_id,
key,
jwt = null,
headers = {},
params = {},
data = {},
method = 'delete', // 'delete', 'disable', 'hide'
return_meta = false,
log_lvl = 0
} : {
api_cfg: any,
obj_type: string,
obj_id: string,
key: string,
jwt?: null|string,
headers?: any,
params?: any,
data?: any,
method?: string,
return_meta?: boolean,
log_lvl?: number
}
) {
if (log_lvl) {
console.log(`*** delete_ae_obj_id_crud() *** obj_type: ${obj_type} obj_id: ${obj_id}`);
}
data['super_key'] = key;
data['jwt'] = jwt;
// NOTE: The key and or JWT should be in the header of the DELETE, GET, PATCH, POST
let endpoint = '';
if (obj_type == 'account') {
endpoint = `/crud/account/${obj_id}`;
} else if (obj_type == 'address') {
endpoint = `/crud/address/${obj_id}`;
} else if (obj_type == 'archive') {
endpoint = `/crud/archive/${obj_id}`;
} else if (obj_type == 'archive_content') {
endpoint = `/crud/archive/content/${obj_id}`;
} else if (obj_type == 'contact') {
endpoint = `/crud/contact/${obj_id}`;
} else if (obj_type == 'data_store') {
endpoint = `/crud/data_store/${obj_id}`;
} else if (obj_type == 'event') {
endpoint = `/crud/event/${obj_id}`;
} else if (obj_type == 'event_abstract') {
endpoint = `/crud/event/abstract/${obj_id}`;
} else if (obj_type == 'event_badge') {
endpoint = `/crud/event/badge/${obj_id}`;
} else if (obj_type == 'event_device') {
endpoint = `/crud/event/device/${obj_id}`;
} else if (obj_type == 'event_exhibit') {
endpoint = `/crud/event/exhibit/${obj_id}`;
} else if (obj_type == 'event_exhibit_tracking') {
endpoint = `/crud/event/exhibit/tracking/${obj_id}`;
} else if (obj_type == 'event_file') {
endpoint = `/crud/event/file/${obj_id}`;
} else if (obj_type == 'event_location') {
endpoint = `/crud/event/location/${obj_id}`;
} else if (obj_type == 'event_person') {
endpoint = `/crud/event/person/${obj_id}`;
} else if (obj_type == 'event_presentation') {
endpoint = `/crud/event/presentation/${obj_id}`;
} else if (obj_type == 'event_presenter') {
endpoint = `/crud/event/presenter/${obj_id}`;
} else if (obj_type == 'event_session') {
endpoint = `/crud/event/session/${obj_id}`;
} else if (obj_type == 'event_track') {
endpoint = `/crud/event/track/${obj_id}`;
} else if (obj_type == 'grant') {
endpoint = `/crud/grant/${obj_id}`;
} else if (obj_type == 'hosted_file') {
endpoint = `/crud/hosted_file/${obj_id}`;
} else if (obj_type == 'journal') {
endpoint = `/crud/journal/${obj_id}`;
} else if (obj_type == 'journal_entry') {
endpoint = `/crud/journal/entry/${obj_id}`;
} else if (obj_type == 'order') {
endpoint = `/crud/order/${obj_id}`;
} else if (obj_type == 'order_line') {
endpoint = `/crud/order/line/${obj_id}`;
} else if (obj_type == 'page') {
endpoint = `/crud/page/${obj_id}`;
} else if (obj_type == 'person') {
endpoint = `/crud/person/${obj_id}`;
} else if (obj_type == 'post') {
endpoint = `/crud/post/${obj_id}`;
} else if (obj_type == 'post_comment') {
endpoint = `/crud/post/comment/${obj_id}`;
} else if (obj_type == 'site') {
endpoint = `/crud/site/${obj_id}`;
} else if (obj_type == 'sponsorship_cfg') {
endpoint = `/crud/sponsorship/cfg/${obj_id}`;
} else if (obj_type == 'sponsorship') {
endpoint = `/crud/sponsorship/${obj_id}`;
// } else if (obj_type == 'user') {
// endpoint = `/crud/user/${obj_id}`;
} else {
console.log(`Unknown object type: ${obj_type}`);
return false;
}
if (log_lvl) {
console.log('Endpoint:', endpoint);
}
if (method) { // NOTE: method options: 'delete', 'disable', 'hide'
params['method'] = method;
}
if (log_lvl) {
console.log('Params:', params);
}
let object_obj_delete_promise = await delete_object({api_cfg: api_cfg, endpoint: endpoint, params: params, data: data, log_lvl: log_lvl});
if (log_lvl > 1) {
console.log(object_obj_delete_promise);
}
return object_obj_delete_promise;
}
/* BEGIN: Hosted File Related */
// Updated 2023-08-17
export let download_hosted_file = async function download_hosted_file(
{
api_cfg,
hosted_file_id,
return_file = true,
filename,
auto_download = false,
params = {},
log_lvl = 0
} : {
api_cfg: any,
hosted_file_id: string,
return_file?: boolean,
filename?: string,
auto_download?: boolean,
params?: key_val,
log_lvl?: number
}
) {
console.log('*** stores_hosted_api.js: download_hosted_file() ***');
let task_id = hosted_file_id;
const endpoint = `/hosted_file/${hosted_file_id}/download`;
if (filename) {
params['filename'] = filename;
}
params['return_file'] = true;
let hosted_file_download_get_promise = await api.get_object({
api_cfg: api_cfg,
endpoint: endpoint,
params: params,
return_blob: return_file,
filename: filename,
auto_download: auto_download,
task_id: task_id,
log_lvl: log_lvl
});
// console.log(hosted_file_download_get_promise);
return hosted_file_download_get_promise;
}
// Updated 2023-12-15
export let delete_hosted_file = async function delete_hosted_file(
{
api_cfg,
hosted_file_id,
link_to_type,
link_to_id,
rm_orphan=false,
params={},
data={},
log_lvl=1
} : {
api_cfg: any,
hosted_file_id: string,
link_to_type?: string,
link_to_id?: string,
rm_orphan?: boolean,
params?: key_val,
data?: key_val,
log_lvl?: number
}
) {
console.log('*** stores_hosted_api.js: delete_hosted_file() ***');
const endpoint = `/hosted_file/${hosted_file_id}`;
if (link_to_type) {
params['link_to_type'] = link_to_type;
}
if (link_to_id) {
params['link_to_id'] = link_to_id;
}
if (rm_orphan) {
params['rm_orphan'] = rm_orphan;
}
let hosted_file_obj_delete_promise = await api.delete_object({api_cfg: api_cfg, endpoint: endpoint, params: params, data: data, log_lvl: log_lvl});
// console.log(hosted_file_obj_delete_promise);
return hosted_file_obj_delete_promise;
}
/* END: Hosted File Related */
/* BEGIN: Data Store Related */
// Updated 2023-06-29
export let get_data_store_obj_w_code = async function get_data_store_obj_w_code({
api_cfg,
data_store_code,
data_type='text',
headers={},
params={},
timeout=25000,
log_lvl=0
} : {
api_cfg: any,
data_store_code: string,
data_type?: string,
headers?: key_val,
params?: key_val,
timeout?: number,
log_lvl?: number
}
) {
if (log_lvl) {
console.log('*** get_data_store_obj_w_code() ***');
}
// let get_item_result = window.localStorage.getItem(code);
const endpoint = `/data_store/code/${data_store_code}`;
let data_store_obj_get_promise = await api.get_object({api_cfg: api_cfg, endpoint: endpoint, headers: headers, params: params, timeout: timeout, log_lvl: log_lvl});
if (data_store_obj_get_promise === false) {
console.log('Data Store - RUN AGAIN WITH BACKUP');
let original_api_base_url = api_cfg['base_url'];
let temp_api = api_cfg;
temp_api['base_url'] = temp_api['base_url_bak']
data_store_obj_get_promise = await api.get_object({api_cfg: temp_api, endpoint: endpoint, headers: headers, params: params, timeout: timeout, log_lvl: log_lvl});
temp_api['base_url'] = original_api_base_url;
}
let data_store_obj = data_store_obj_get_promise;
if (data_type == 'text') {
// console.log(data_store_obj.text);
// window.localStorage.setItem(data_store_code, data_store_obj.text);
// localStorage.setItem(data_store_code, data_store_obj.text);
} else if (data_type == 'json') {
// console.log(data_store_obj.json);
// window.localStorage.setItem(data_store_code, JSON.stringify(data_store_obj.json));
// localStorage.setItem(data_store_code, JSON.stringify(data_store_obj.json));
}
if (log_lvl > 1) {
console.log('Response Data:', data_store_obj);
}
return data_store_obj;
}
/* END: Data Store Related */
/* BEGIN: Utility: Email Related */
// Updated 2023-06-29
export let send_email = async function send_email(
{
api_cfg,
from_email,
from_name = '',
to_email,
to_name = '',
cc_email = null,
cc_name = null,
bcc_email = null,
bcc_name = null,
subject,
body_html,
body_text = null,
// headers = {},
params = {},
data = {},
return_obj = false,
return_meta = false,
test = false,
log_lvl = 0
} : {
api_cfg: any,
from_email: string,
from_name?: string,
to_email: string,
to_name?: string,
cc_email?: null|string,
cc_name?: null|string,
bcc_email?: null|string,
bcc_name?: null|string,
subject: string,
body_html: string,
body_text?: null|string,
// headers?: key_val,
params?: key_val,
data?: key_val,
return_obj?: boolean,
return_meta?: boolean,
test?: boolean,
log_lvl?: number
}
) {
console.log('*** send_email() ***');
let endpoint = `/util/email/send`;
data['from_email'] = from_email; // Required
data['from_name'] = from_name;
data['to_email'] = to_email; // Required
data['to_name'] = to_name;
data['cc_email'] = cc_email;
data['cc_name'] = cc_name;
data['bcc_email'] = bcc_email;
data['bcc_name'] = bcc_name;
data['subject'] = subject;
if (log_lvl) {
console.log('Data:', data);
}
data['body_html'] = body_html;
data['body_text'] = body_text;
if (return_obj) {
params['return_obj'] = true;
}
if (test) {
params['test'] = true;
}
let send_email_post_promise = await api.post_object({
api_cfg: api_cfg,
endpoint: endpoint,
params: params,
data: data,
return_meta: return_meta,
log_lvl: log_lvl
});
if (log_lvl > 1) {
console.log('Response Data:', send_email_post_promise);
}
if (return_obj) {
return send_email_post_promise;
} else {
return send_email_post_promise.event_abstract_id_random;
}
}
/* END: Utility: Email Related */
let obj = {
delete_object: delete_object,
get_object: get_object,
patch_object: patch_object,
post_object: post_object,
get_ae_obj_id_crud: get_ae_obj_id_crud,
get_ae_obj_li_for_obj_id_crud: get_ae_obj_li_for_obj_id_crud,
get_ae_obj_li_for_obj_id_crud_v2: get_ae_obj_li_for_obj_id_crud_v2,
create_ae_obj_crud: create_ae_obj_crud,
update_ae_obj_id_crud: update_ae_obj_id_crud,
delete_ae_obj_id_crud: delete_ae_obj_id_crud,
download_hosted_file: download_hosted_file,
delete_hosted_file: delete_hosted_file,
get_data_store_obj_w_code: get_data_store_obj_w_code,
send_email: send_email,
}
export let api = obj;
// module.exports = api;

149
src/lib/db_archives.ts Normal file
View File

@@ -0,0 +1,149 @@
import Dexie, { type Table } from 'dexie';
import type { key_val } from './ae_stores';
// li = list
// kv = key value list
// Updated 2024-09-25
export interface Archive {
id: string;
// id_random: string;
archive_id: string;
// archive_id_random: string;
code?: null|string;
account_id: string;
// account_id_random: string;
// archive_type: string;
// type: string;
name: string;
// summary?: null|string;
description?: null|string;
content_html?: null|string;
content_json?: null|string;
content_url?: null|string;
content_url_text?: null|string;
original_datetime?: Date;
original_timezone?: null|string;
original_location?: null|string;
original_url?: null|string;
original_url_text?: null|string;
// meta_data?: null|string;
// access_key?: null|string; /// Rename this to "passcode" if used later
sort_by?: null|string;
sort_by_desc?: null|string;
cfg_json?: null|key_val;
enable: null|boolean;
hide?: null|boolean;
priority?: null|boolean
sort?: null|number;
group?: null|string;
notes?: null|string;
created_on: Date;
updated_on?: null|Date;
// Additional fields for convenience (database views)
// archive_content_count?: number;
// archive_content_kv?: null|key_val;
// archive_content_li?: null|[];
}
// Updated 2024-09-25
export interface Archive_Content {
id: string;
// id_random: string;
archive_content_id: string;
// archive_content_id_random: string;
archive_id: string;
// archive_id_random: string;
archive_content_type: string;
name: string;
description?: null|string;
content_html?: null|string;
content_json?: null|string;
url?: null|string;
url_text?: null|string;
hosted_file_id?: string;
file_path?: null|string;
filename?: null|string;
file_extension?: null|string;
original_datetime?: Date;
original_timezone?: null|string;
original_location?: null|string;
original_url?: null|string;
original_url_text?: null|string;
// meta_data?: null|string;
// access_key?: null|string; /// Rename this to "passcode" if used later
enable_for_public?: boolean;
cfg_json?: null|key_val;
enable: null|boolean;
hide?: null|boolean;
priority?: null|boolean
sort?: null|number;
group?: null|string;
notes?: null|string;
created_on: Date;
updated_on?: null|Date;
// Additional fields for convenience (database views)
archive_code?: null|string;
archive_name?: null|string;
}
// Updated 2024-09-25
export class MySubClassedDexie extends Dexie {
// We just tell the typing system this is the case
archive!: Table<Archive>;
content!: Table<Archive_Content>;
constructor() {
super('ae_archives_db');
this.version(1).stores({
archive: `
id, archive_id,
code,
account_id,
name,
original_datetime, original_timezone, original_location,
enable, hide, priority, sort, group, notes, created_on, updated_on`,
content: `
id, archive_content_id,
archive_id,
archive_content_type,
name,
hosted_file_id,
file_path,
filename, file_extension,
original_datetime, original_timezone, original_location, original_url, original_url_text,
enable_for_public,
enable, hide, priority, sort, group, notes, created_on, updated_on`,
});
}
}
export const db_archives = new MySubClassedDexie();

97
src/lib/db_core.ts Normal file
View File

@@ -0,0 +1,97 @@
import Dexie, { type Table } from 'dexie';
// li = list
// kv = key value list
// Updated 2024-07-17
export interface Person {
id: string;
// id_random: string;
person_id: string;
person_id_random: string;
external_id?: string; // This may be semi-random or unique only withing the account.
external_sys_id?: string; // Generated by an external system. Ideally this should be something like a UUID. It may be the same as the external_id if nothing given.
code?: string; // Not currently used.
account_id?: string; // Technically this is not required for global users.
account_id_random?: string; // Technically this is not required for global users.
person_profile_id?: null|string;
person_profile_id_random?: null|string; // The new table person_profile will be used soon...
user_id?: string;
user_id_random?: string;
pronouns?: null|string;
informal_name?: null|string;
title_names?: null|string;
given_name: string;
middle_name?: null|string;
family_name: null|string;
designations?: null|string;
professional_title?: null|string;
full_name?: string;
affiliations?: null|string;
primary_email?: string;
biography?: null|string;
agree?: null|boolean;
comments?: null|string;
allow_auth_key?: null|boolean; // For sign in without password
auth_key?: null|string;
passcode?: null|string;
data_json?: null|string;
enable: null|boolean;
hide?: null|boolean;
priority?: null|boolean
sort?: null|number;
group?: null|string;
notes?: null|string;
created_on: Date;
updated_on?: null|Date;
// Additional fields for convenience (database views)
username?: string;
user_name?: null|string;
user_email?: null|string;
user_allow_auth_key?: null|boolean; // For sign in without password
user_super?: boolean;
user_manager?: boolean;
user_administrator?: boolean;
user_public?: boolean;
}
// Updated 2024-06-24
export class MySubClassedDexie extends Dexie {
person!: Table<Person>;
// user!: Table<User>;
constructor() {
super('ae_core_db');
this.version(1).stores({
person: `
id, person_id, person_id_random,
external_id, code,
account_id, user_id,
account_id_random, user_id_random,
person_profile_id,
person_profile_id_random,
given_name, family_name,
full_name, affiliations, email,
agree,
enable, hide, priority, sort, group, created_on, updated_on`,
});
}
}
export const db_core = new MySubClassedDexie();

668
src/lib/db_events.ts Normal file
View File

@@ -0,0 +1,668 @@
import Dexie, { type Table } from 'dexie';
import type { key_val } from './ae_stores';
// li = list
// kv = key value list
export interface Event {
id: string;
// id_random: string;
event_id: string;
event_id_random: string;
code: string;
account_id: string;
account_id_random: string;
conference: boolean;
type: string;
name: string;
summary?: null|string;
description?: null|string;
start_datetime?: Date;
end_datetime?: Date;
timezone?: null|string;
location_address_json?: null|string;
mod_abstracts_json?: null|key_val;
mod_badges_json?: null|key_val;
mod_exhibits_json?: null|key_val;
mod_pres_mgmt_json?: null|key_val;
cfg_json?: null|key_val;
enable: null|boolean;
hide: null|boolean;
priority: null|boolean
sort: null|number;
group: null|string;
notes: null|string;
created_on: Date;
updated_on: null|Date;
// IDAA Recovery Meetings
contact_li_json?: null|string[]; // full_name, email, phone_mobile, phone_home, phone_office, other_text
external_person_id?: null|string;
physical?: null|boolean;
virtual?: null|boolean;
weekday_sunday?: null|boolean;
weekday_monday?: null|boolean;
weekday_tuesday?: null|boolean;
weekday_wednesday?: null|boolean;
weekday_thursday?: null|boolean;
weekday_friday?: null|boolean;
weekday_saturday?: null|boolean;
recurring_start_time?: null|string;
// Additional fields for convenience (database views)
file_count?: null|number;
file_count_all?: null|number;
internal_use_count?: null|number;
event_file_id_li_json?: null|string;
}
export interface Badge {
// id?: number;
id_random: string;
event_badge_id_random: string;
event_id_random: string;
pronouns: null|string;
informal_name: null|string;
title_names: null|string;
given_name: string;
middle_name: null|string;
family_name: null|string;
designations: null|string;
professional_title: null|string;
professional_title_override: null|string;
full_name: string;
full_name_override: null|string;
affiliations: string;
affiliations_override: null|string;
email: string;
email_override: null|string;
address_line_1: null|string;
address_line_2: null|string;
address_line_3: null|string;
city: null|string;
country_subdivision_code: null|string;
state_province: null|string;
state_province_abb: null|string;
postal_code: null|string;
country_alpha_2_code: null|string;
country: null|string;
full_address: null|string;
location: null|string;
location_override: null|string;
query_str: null|string;
badge_type: string;
badge_type_code: string;
badge_type_code_override: null|string;
badge_type_override: null|string;
external_event_id: string;
external_id: string;
external_person_id: string;
enable: null|boolean;
hide: null|boolean;
priority: null|boolean
sort: null|number;
group: null|string;
notes: null|string;
created_on: Date;
updated_on: null|Date;
}
export interface Exhibit {
// id?: number;
id_random: string;
event_exhibit_id_random: string;
event_id_random: string;
code: string;
name: string;
// tagline: null|string;
description: null|string;
staff_passcode: null
data_json: null|string;
leads_api_access: null|boolean;
leads_custom_questions_json: null|string;
leads_device_sm_qty: null|number;
leads_device_lg_qty: null|number;
license_max: number;
license_li_json: null|string;
cfg_json: string;
enable: null|boolean;
hide: null|boolean;
priority: null|boolean
sort: null|number;
group: null|string;
notes: null|string;
created_on: Date;
updated_on: null|Date;
}
export interface Exhibit_tracking {
// id?: number;
id_random: string;
event_exhibit_tracking_id_random: string;
event_exhibit_id_random: string;
event_badge_id_random: string;
event_person_id_random: null|string; // Is this needed?
external_person_id: null|string; // This is an email address
exhibitor_notes: null|string;
responses_json: null|string;
data_json: null|string;
event_exhibit_name: string; // Extra field for convenience
event_badge_title_names: null|string;
event_badge_given_name: string;
event_badge_family_name: null|string;
event_badge_designations: null|string;
event_badge_full_name: string;
event_badge_full_name_override: null|string;
event_badge_professional_title: null|string;
event_badge_professional_title_override: null|string;
event_badge_affiliations: null|string;
event_badge_affiliations_override: null|string;
event_badge_email: null|string;
event_badge_email_override: null|string;
event_badge_location: null|string;
event_badge_location_override: null|string;
event_badge_country: null|string;
enable: null|boolean;
hide: null|boolean;
priority: null|boolean
sort: null|number;
group: null|string;
notes: null|string;
created_on: Date;
updated_on: null|Date;
}
export interface File {
id: string;
id_random: string;
event_file_id: string;
event_file_id_random: string;
hosted_file_id: string;
hosted_file_id_random: string;
hash_sha256: string;
for_type?: string;
for_id?: string;
for_id_random?: string;
event_id_random: string;
event_session_id_random?: string;
event_presentation_id_random?: string;
event_presenter_id_random?: string;
event_location_id_random?: string;
filename: string;
extension: string;
open_in_os?: null|string; // null, empty, 'mac', or 'win'
lu_file_purpose_id: string;
lu_event_file_purpose_name: string;
file_purpose: string;
enable: null|boolean;
hide?: null|boolean;
priority?: null|boolean
sort?: null|number;
group?: null|string;
notes?: null|string;
created_on: Date;
updated_on?: null|Date;
// Additional fields for convenience (database views)
filename_no_ext: string;
filename_w_ext: string;
hosted_file_content_type: string;
file_size: number; // In bytes
hosted_file_size?: number; // In bytes
event_location_code?: null|string;
event_location_name?: null|string;
event_session_code?: null|string;
event_session_type_code?: null|string;
event_session_name?: string;
event_session_start_datetime?: null|Date;
event_session_end_datetime?: null|Date;
event_presentation_code?: null|string;
event_presentation_type_code?: null|string;
event_presentation_name?: string;
event_presentation_start_datetime?: null|Date;
event_presentation_end_datetime?: null|Date;
event_presenter_given_name?: null|string;
event_presenter_family_name?: null|string;
event_presenter_full_name?: null|string;
event_presenter_email?: null|string;
}
// Updated 2024-06-25
export interface Location {
id: string;
// id_random: string;
event_location_id: string;
event_location_id_random: string;
external_id?: null|string;
code?: null|string;
type_code?: string;
event_id: string;
event_id_random: string;
name: string;
description?: null|string;
passcode?: null|string;
hide_event_launcher?: null|boolean;
alert?: null|boolean;
alert_msg?: null|string;
data_json?: null|string;
enable: null|boolean;
hide?: null|boolean;
priority?: null|boolean
sort?: null|number;
group?: null|string;
notes?: null|string;
created_on: Date;
updated_on?: null|Date;
// Additional fields for convenience (database views)
file_count?: null|number;
file_count_all?: null|number;
internal_use_count?: null|number;
event_file_id_li_json?: null|string;
event_name?: null|string;
// A key value list of the sessions
event_session_kv?: null|key_val;
// A key value list of the files
event_file_kv?: null|key_val;
}
// Updated 2024-06-10
export interface Presentation {
id: string;
// id_random: string;
event_presentation_id: string;
event_presentation_id_random: string;
external_id?: null|string;
code?: null|string;
for_type?: string;
for_id?: string;
for_id_random?: string;
type_code?: string;
event_id: string;
event_id_random: string;
event_session_id: string;
event_session_id_random: string;
event_abstract_id?: null|string;
event_abstract_id_random?: null|string;
abstract_code?: null|string;
name: string;
description?: null|string;
start_datetime?: null|Date;
end_datetime?: null|Date;
passcode?: null|string;
hide_event_launcher?: null|boolean;
enable: null|boolean;
hide?: null|boolean;
priority?: null|boolean;
sort?: null|number;
group?: null|string;
notes?: null|string;
created_on: Date;
updated_on?: null|Date;
// Additional fields for convenience (database views)
// file_count: null|number;
event_session_code?: null|string;
event_session_name?: null|string;
// A key value list of the presenters
event_presenter_kv?: null|key_val;
event_presenter_li?: null|list;
}
// Updated 2024-06-10
export interface Presenter {
id: string;
// id_random: string;
event_presenter_id: string;
event_presenter_id_random: string;
external_id?: string;
code?: string;
event_id: string;
event_id_random: string;
event_session_id: string;
event_session_id_random: string;
event_person_id?: null|string;
event_person_id_random?: null|string;
event_presentation_id: string;
event_presentation_id_random: string;
person_id?: null|string;
person_id_random?: null|string;
person_profile_id?: null|string;
person_profile_id_random?: null|string; // The new table person_profile will be used soon...
pronouns?: null|string;
informal_name?: null|string;
title_names?: null|string;
given_name: string;
middle_name?: null|string;
family_name?: null|string;
designations?: null|string;
professional_title?: null|string;
full_name?: string;
affiliations?: null|string;
email?: string;
biography?: null|string;
agree?: null|boolean; // General catchall for agreement or consent
comments?: null|string;
passcode?: null|string;
hide_event_launcher?: null|boolean;
data_json?: null|string;
enable: null|boolean;
hide?: null|boolean;
priority?: null|boolean
sort?: null|number;
group?: null|string;
notes?: null|string;
created_on?: Date;
updated_on?: null|Date;
// Additional fields for convenience (database views)
file_count?: null|number;
// file_count_all?: null|number;
// internal_use_count?: null|number;
event_file_id_li_json?: null|string;
event_session_code?: null|string;
event_session_name?: string;
event_session_start_datetime?: null|Date;
event_presentation_code?: null|string;
event_presentation_name?: string;
event_presentation_start_datetime?: null|Date;
person_external_id?: null|string; // This may be semi-random or unique only withing the account.
person_external_sys_id?: null|string; // Generated by an external system. Ideally this should be something like a UUID. It may be the same as the external_id if nothing given.
person_given_name?: string;
person_family_name?: null|string;
person_full_name?: null|string;
person_professional_title?: null|string;
person_affiliations?: null|string;
person_primary_email?: null|string;
person_passcode?: null|string;
// A key value list of the files
event_file_kv?: null|key_val;
}
export interface Registration {
// Nothing here yet
}
// Updated 2024-06-19
export interface Session {
id: string;
// id_random: string;
event_session_id: string;
event_session_id_random: string;
external_id: null|string;
code: null|string;
for_type: string;
for_id: string;
for_id_random: string;
type_code?: string;
event_id: string;
event_id_random: string;
event_location_id?: null|string;
event_location_id_random?: null|string;
poc_person_id?: null|string;
poc_person_id_random?: null|string;
poc_agree?: null|boolean; // General catchall for agreement or consent by the POC
poc_kv_json?: null|key_val; // Key value list of the POC by type (examples: 'advocate', 'chair', 'champion', 'moderator', 'organizer')
name: string;
description?: null|string;
start_datetime?: null|Date;
end_datetime?: null|Date;
passcode?: null|string;
hide_event_launcher?: null|boolean;
alert?: null|boolean;
alert_msg?: null|string;
data_json?: null|string;
ux_mode?: null|string; // 'colloquium', 'lecture', 'panel', 'poster', 'symposium', 'workshop'
// colloquium - Specialists present on related topics with questions
// symposium - A discussion, less formal
enable: null|boolean;
hide: null|boolean;
priority: null|boolean
sort: null|number;
group: null|string;
notes: null|string;
created_on: Date;
updated_on: null|Date;
// Additional fields for convenience (database views)
file_count?: null|number; // Only files directly under a session
file_count_all?: null|number; // All files under a session
internal_use_count?: null|number; // Files marked for internal use
event_file_id_li_json?: null|string;
poc_person_given_name?: null|string;
poc_person_family_name?: null|string;
poc_person_full_name?: null|string;
poc_person_primary_email?: null|string;
poc_person_passcode?: null|string;
event_name?: null|string;
event_location_code?: null|string;
event_location_name?: null|string;
// A key value list of the presentations
event_presentation_kv?: null|key_val;
event_presentation_li?: null|[any];
// A key value list of the files
event_file_kv?: null|key_val;
event_file_li?: null|[any];
}
// Updated 2024-06-10
export class MySubClassedDexie extends Dexie {
// 'badges' is added by dexie when declaring the stores()
// We just tell the typing system this is the case
events!: Table<Event>;
badges!: Table<Badge>;
exhibits!: Table<Exhibit>;
exhibit_tracking!: Table<Exhibit_tracking>;
files!: Table<File>;
locations!: Table<Location>;
sessions!: Table<Session>;
presentations!: Table<Presentation>;
presenters!: Table<Presenter>;
constructor() {
super('ae_events_db');
this.version(3).stores({
events: `
id, event_id, event_id_random,
code,
account_id, account_id_random,
conference, type,
name,
start_datetime, end_datetime,
timezone,
cfg_json,
enable, hide, priority, sort, group, notes, created_on, updated_on`,
// badges: '++id, full_name, email' // Primary key and indexed props
badges: `
id_random, event_badge_id_random, event_id_random,
full_name, full_name_override, email, email_override,
affiliations, affiliations_override,
badge_type, badge_type_code, badge_type_code_override, badge_type_override,
external_event_id, external_id, external_person_id,
enable, hide, priority, sort, group, notes, created_on, updated_on`,
exhibits: `
id_random, event_exhibit_id_random,
code, name, description, staff_passcode,
data_json, license_max, license_li_json, cfg_json,
enable, hide, priority, sort, group, notes, created_on, updated_on, [priority+name]`,
exhibit_tracking: `
id_random, event_exhibit_tracking_id_random, event_exhibit_id_random, event_badge_id_random, event_person_id_random,
exhibitor_notes, responses_json, data_json,
event_badge_full_name, event_badge_email,
enable, hide, priority, sort, group, notes, created_on, updated_on`,
files: `
id, id_random, event_file_id, event_file_id_random,
hosted_file_id, hosted_file_id_random,
hash_sha256,
for_type, for_id, for_id_random,
event_id_random, event_session_id_random, event_presentation_id_random, event_presenter_id_random, event_location_id_random,
filename, extension,
lu_file_purpose_id, lu_event_file_purpose_name, file_purpose,
enable, hide, priority, sort, group, created_on, updated_on`,
locations: `
id, event_location_id, event_location_id_random,
external_id, code,
event_id, event_id_random,
name, description,
passcode,
hide_event_launcher,
alert, alert_msg,
data_json,
enable, hide, priority, sort, group, created_on, updated_on`,
presentations: `
id, event_presentation_id, event_presentation_id_random,
external_id, code,
for_type, for_id, for_id_random,
type_code,
event_id_random, event_session_id_random, event_abstract_id_random,
abstract_code, name, description, start_datetime, end_datetime,
hide_event_launcher,
enable, hide, priority, sort, group, created_on, updated_on`,
presenters: `
id, event_presenter_id, event_presenter_id_random,
external_id, code,
event_id, event_session_id, event_person_id, event_presentation_id,
event_id_random, event_session_id_random, event_person_id_random, event_presentation_id_random,
person_id, person_profile_id,
person_id_random, person_profile_id_random,
given_name, family_name,
full_name, affiliations, email,
agree,
hide_event_launcher,
enable, hide, priority, sort, group, created_on, updated_on`,
sessions: `
id, event_session_id, event_session_id_random,
external_id, code,
for_type, for_id, for_id_random,
type_code,
event_id, event_location_id,
poc_person_id,
event_id_random, event_location_id_random,
poc_person_id_random,
name, start_datetime, end_datetime,
hide_event_launcher,
ux_mode,
enable, hide, priority, sort, group, created_on, updated_on`,
});
}
}
export const db_events = new MySubClassedDexie();

148
src/lib/db_notes.ts Normal file
View File

@@ -0,0 +1,148 @@
import Dexie, { type Table } from 'dexie';
import type { key_val } from './ae_stores';
// li = list
// kv = key value list
// json = JSON string
// ux = user experience (mode)
// LLM = Large Language Model (AI)
// Updated 2024-08-20
export interface Note {
id: string; // actually "id_random"
note_id: string;
// Essentially this is a change log of notes
snapshot_id?: string; // This is the original note ID. If deleted, then delete all children notes.
previous_id?: null|string; // This is the old or parent note ID
next_id?: null|string; // This is the new or child note ID
external_id?: null|string;
import_id?: null|string;
code?: null|string;
for_type?: null|string;
for_id?: null|string;
type_code?: null|string;
account_id?: null|string; // Owner account of the note
person_id?: null|string; // Owner person of the note
// event_id?: null|string; // Assign to an event???
// location_id?: null|string; // Assign to a location???
name: string; // or the title
summary?: null|string; // LLM (AI) generated summary...???
outline?: null|string; // LLM (AI) generated outline...???
note?: null|string;
note_html?: null|string;
note_json?: null|string;
start_datetime?: null|Date;
end_datetime?: null|Date;
timezone?: null|string;
hide_event_launcher?: null|boolean;
alert?: null|boolean; // LLM (AI) generated summary...???
alert_msg?: null|string; // LLM (AI) generated summary...???
data_json?: null|string; // We always need to store something extra...
ux_mode?: null|string; // 'mobile' or 'desktop'
// This only allows for basic access to the content.
passcode_read?: null|string; // For LLM (AI) generated summary...???
passcode_read_expire?: null|Date;
passcode_write?: null|string;
passcode_write_expire?: null|Date
enable: null|boolean;
hide?: null|boolean;
priority?: null|boolean
sort?: null|number;
group?: null|string;
notes?: null|string;
created_on: Date;
updated_on?: null|Date;
// Additional fields for convenience (database views)
file_count?: null|number; // Only files directly under a note
note_file_id_li_json?: null|string;
// One person
person__given_name?: null|string;
person__family_name?: null|string;
person__full_name?: null|string;
person__primary_email?: null|string;
person__passcode?: null|string;
// JSON formatted key value pairs for multiple people: {id: name, email, etc.}
person__kv_json?: null|string;
note_name?: null|string;
note_location_code?: null|string;
note_location_name?: null|string;
// A key value list of the presentations
note_presentation_kv?: null|key_val;
note_presentation_li?: null|[];
// A key value list of the files
note_file_kv?: null|key_val;
note_file_li?: null|[];
// note_collection_id?: null|string; // For a collection of notes?
// Future standard fields!!!
obj_id?: null|string;
obj_ext_uid?: null|string; // Probably not needed for notes
obj_ext_id?: null|string; // Probably not needed for notes
obj_import_id?: null|string; // Probably not needed for notes
obj_code?: null|string;
obj_account_id?: null|string;
obj_passcode?: null|string;
obj_type?: null|string; // Should always be 'note' in this case
obj_type_ver_id?: null|string; // The ID from the table for the object type
obj_name?: null|string;
obj_summary?: null|string; // LLM (AI) generated summary...???
obj_outline?: null|string; // LLM (AI) generated outline...???
obj_description?: null|string; // Probably not needed for notes
obj_enable?: null|boolean;
obj_enable_on?: null|Date;
obj_archive_on?: null|Date;
obj_hide?: null|boolean;
obj_priority?: null|number;
obj_sort?: null|number;
obj_group?: null|string;
obj_cfg_json?: null|string;
obj_notes?: null|string; // Not the same as the "note" in the object type named "Note".
obj_created_on?: Date;
obj_updated_on?: null|Date;
}
// Updated 2024-06-10
export class MySubClassedDexie extends Dexie {
// We just tell the typing system this is the case
note!: Table<Note>;
constructor() {
super('ae_notes_db');
this.version(1).stores({
note: `
id, note_id,
code,
account_id,
conference, type,
name,
start_datetime, end_datetime,
timezone,
enable, hide, priority, sort, group, notes, created_on, updated_on`,
});
}
}
export const db_notes = new MySubClassedDexie();

117
src/lib/db_posts.ts Normal file
View File

@@ -0,0 +1,117 @@
import Dexie, { type Table } from 'dexie';
import type { key_val } from './ae_stores';
// li = list
// kv = key value list
// Updated 2024-09-25
export interface Post {
id: string;
// id_random: string;
post_id: string;
// post_id_random: string;
account_id: string;
// account_id_random: string;
person_id?: null|string;
external_person_id?: null|string; // For IDAA this is the Novi UUID
user_id?: null|string;
topic_id?: string;
topic?: string; // or topic_name?
topic_name?: string;
// name: null|string;
// summary?: null|string;
title: null|string;
content?: null|string;
anonymous?: null|boolean;
full_name?: null|string;
email?: null|string;
enable_comments?: null|boolean;
archive?: null|boolean;
archive_on?: Date;
cfg_json?: null|key_val;
enable: null|boolean;
hide?: null|boolean;
priority?: null|boolean
sort?: null|number;
group?: null|string;
notes?: null|string;
created_on: Date;
updated_on?: null|Date;
// Additional fields for convenience (database views)
post_comment_count?: number;
}
// Updated 2024-09-25
export interface Post_Comment {
id: string;
// id_random: string;
post_comment_id: string;
// post_comment_id_random: string;
post_id: string;
// post_id_random: string;
// name: null|string;
// summary?: null|string;
title: null|string;
content?: null|string;
anonymous?: null|boolean;
full_name?: null|string;
email?: null|string;
cfg_json?: null|key_val;
enable: null|boolean;
hide?: null|boolean;
priority?: null|boolean
sort?: null|number;
group?: null|string;
notes?: null|string;
created_on: Date;
updated_on?: null|Date;
// Additional fields for convenience (database views)
}
// Updated 2024-09-25
export class MySubClassedDexie extends Dexie {
// We just tell the typing system this is the case
post!: Table<Post>;
comment!: Table<Post_Comment>;
constructor() {
super('ae_posts_db');
this.version(1).stores({
post: `
id, post_id,
account_id,
topic_id, topic,
title,
full_name, email,
archive, archive_on,
enable, hide, priority, sort, group, notes, created_on, updated_on`,
comment: `
id, post_comment_id,
post_id,
title,
full_name, email,
enable, hide, priority, sort, group, notes, created_on, updated_on`,
});
}
}
export const db_posts = new MySubClassedDexie();

1391
src/lib/electron_native.js Normal file

File diff suppressed because it is too large Load Diff

318
src/lib/electron_relay.js Normal file
View File

@@ -0,0 +1,318 @@
/* ### Electron Specific JavaScript ### */
// import crypto from 'crypto';
// import {fs} from 'fs';
// import path from 'path';
// const crypto = require('crypto');
// const fs = require('fs');
// const fs_promises = require('node:fs/promises');
// const path = require('path');
// const { ipcRenderer } = require('electron');
// function sleep(milliseconds) {
// const date = Date.now();
// let currentDate = null;
// do {
// currentDate = Date.now();
// } while (currentDate - date < milliseconds);
// }
// // exports.check_hash_file_cache should no longer be needed with this.
// // Updated 2022-10-11
// export let check_hash_file_cache_v2 = async function check_hash_file_cache_v2({local_file_cache_path, hash, check_hash=false}) {
// console.log('*** check_hash_file_cache_v2() ***');
// console.log(`Host File Cache Path: ${local_file_cache_path}; Hash: ${hash}`);
// let hash_filename = `${hash}.file`;
// let subdirectory = hash_filename.substring(0,2);
// let subdirectory_path = path.join(local_file_cache_path, subdirectory);
// if (fs.existsSync(subdirectory_path)) {
// } else {
// console.log(`Hashed file subdirectory not found in cache: ${subdirectory_path}`);
// return null;
// }
// let hash_file_cache_path = path.join(subdirectory_path, hash_filename);
// if (fs.existsSync(hash_file_cache_path)) {
// console.log(`Hashed file exists in cache: ${hash_file_cache_path}`);
// if (check_hash) {
// const file_buffer = fs.readFileSync(hash_file_cache_path);
// const file_hash_sha256 = crypto.createHash('sha256');
// file_hash_sha256.update(file_buffer);
// const file_hash_sha256_check = file_hash_sha256.digest('hex');
// if (file_hash_sha256_check == hash) {
// console.log('File hash match', file_hash_sha256_check);
// } else {
// console.log('File hash does not match', file_hash_sha256_check);
// return false;
// }
// }
// return true;
// } else {
// console.log(`Hashed file not found in cache: ${hash_file_cache_path}`);
// return null;
// }
// }
// Updated 2022-05-07
export let kill_processes = async function kill_processes({process_name_li=[]}) {
console.log('*** kill_processes() ***');
console.log(`Process Name List: ${process_name_li}`);
let fail_flag = null;
if (process_name_li) {
for (let i = 0; i < process_name_li.length; i++) {
// separate the keys and the values
let process_name = process_name_li[i];
let signal = null;
if (process_name == 'osit_aperture_wrapper') {
signal = 'INT'; // INT (interrupt) correctly stops the wrapper
}
let kill_processes_result = await native_app.kill_processes({process_name: process_name, signal: signal});
console.log(kill_processes_result);
if (kill_processes_result) {
console.log('Killed process.');
// return kill_processes_result;
} else {
console.log('Did not kill process. Something went wrong.');
fail_flag = true;
// return false;
}
}
}
return fail_flag;
// let kill_processes_result = await native_app.kill_processes({process_name: process_name});
// console.log(kill_processes_result);
// if (kill_processes_result) {
// console.log('Killed process.');
// return kill_processes_result;
// } else {
// console.log('Did not kill process. Something went wrong.');
// return false;
// }
}
// Updated 2022-05-06
export let open_local_file = async function open_local_file({file_path, filename}) {
console.log('*** open_local_file() ***');
console.log(`File Path: ${file_path}; Filename: ${filename}`);
console.log('Process: Check local hash file cache, Download hash file to cache, and Open cached hash file after copying to temp directory');
// let check_local_file_result = await native_app.check_local_file({local_file_path: file_path, filename: filename});
// console.log(check_local_file_result);
// if (check_local_file_result) {
// console.log('Local file found.');
// } else {
// console.log('Local file not found. Will not attempt to open.');
// return false;
// }
// console.log('Local file file found and ready to be opened.');
let open_local_file_result = await native_app.open_local_file({local_file_path: file_path, filename: filename});
console.log(open_local_file_result);
if (open_local_file_result) {
console.log('Local file was opened.');
return open_local_file_result;
} else {
console.log('Local file was not opened. Something went wrong.');
return false;
}
}
// exports.open_local_file should no longer be needed with this.
// Updated 2022-10-11
export let open_local_file_v2 = async function open_local_file_v2({file_path, filename}) {
console.log('*** open_local_file_v2() ***');
console.log(`Local File Path: ${file_path}; Filename: ${filename}`);
console.log('Process: Check local hash file cache, Download hash file to cache, and Open cached hash file after copying to temp directory');
let open_local_file_result = await ipcRenderer.invoke('open_local_file', file_path, filename).then((result) => {
console.log('IPC open local file finished');
if (result) {
console.log('Local file was opened.');
return result;
} else {
console.log('Local file was not opened. Something went wrong.');
console.log(result);
return false;
}
console.log(result);
return true;
})
return open_local_file_result;
}
// // Updated 2022-05-06
// export let open_hash_file_to_temp = async function open_hash_file_to_temp({local_file_cache_path, hash, host_file_temp_path, filename}) {
// console.log('*** open_hash_file_to_temp() ***');
// console.log(`Host File Cache Path: ${local_file_cache_path}; Hash: ${hash}; Host File Temp Path: ${host_file_temp_path}; Filename: ${filename}`);
// console.log('Process: Check local hash file cache, Download hash file to cache, and Open cached hash file after copying to temp directory');
// let open_hash_file_to_temp_result = await native_app.open_hash_file_to_temp({local_file_cache_path: local_file_cache_path, hash: hash, host_file_temp_path: host_file_temp_path, filename: filename});
// console.log(open_hash_file_to_temp_result);
// if (open_hash_file_to_temp_result) {
// console.log('Local hash file was opened from temp directory.');
// return open_hash_file_to_temp_result;
// } else {
// console.log('Local hash file was not opened from the temp directory. Something went wrong.');
// return false;
// }
// }
// // exports.open_hash_file_to_temp should no longer be needed with this.
// // Updated 2022-10-11
// export let open_hash_file_to_temp_v2 = async function open_hash_file_to_temp_v2({local_file_cache_path, hash, host_file_temp_path, filename}) {
// console.log('*** open_hash_file_to_temp_v2() ***');
// console.log(`Host File Cache Path: ${local_file_cache_path}; Hash: ${hash}; Host File Temp Path: ${host_file_temp_path}; Filename: ${filename}`);
// console.log('Process: Check local hash file cache, Download hash file to cache, and Open cached hash file after copying to temp directory');
// let subdirectory = hash.substring(0,2);
// let subdirectory_path = path.join(local_file_cache_path, subdirectory);
// if (fs.existsSync(subdirectory_path)) {
// } else {
// console.log(`Hashed file subdirectory not found in cache: ${subdirectory_path}`);
// return null;
// }
// let hash_filename = hash+'.file';
// let full_cache_file_path = path.join(subdirectory_path, hash_filename);
// console.log(full_cache_file_path);
// const file_buffer = fs.readFileSync(full_cache_file_path);
// const file_hash_sha256 = crypto.createHash('sha256');
// file_hash_sha256.update(file_buffer);
// const file_hash_sha256_check = file_hash_sha256.digest('hex');
// if (file_hash_sha256_check == hash) {
// console.log('File hash match', file_hash_sha256_check);
// } else {
// console.log('File hash does not match', file_hash_sha256_check);
// // await setTimeout(async () => {console.log('Done waiting????'); open_file_clicked = false;}, 5000);
// // sleep(6000);
// // console.log('???????? WAITED X SECONDS ????????');
// return false;
// }
// let open_hash_file_to_temp_result = await ipcRenderer.invoke('open_hash_file_to_temp', subdirectory_path, hash, host_file_temp_path, filename).then((result) => {
// console.log('IPC open hash file to temp finished');
// if (result) {
// console.log('Local hash file was opened from temp directory.');
// return result;
// } else {
// console.log('Local hash file was not opened from the temp directory. Something went wrong.');
// console.log(result);
// return false;
// }
// })
// return open_hash_file_to_temp_result;
// }
// Updated 2022-05-07
export let run_cmd = async function run_cmd({cmd=null, return_stdout=null}) {
console.log('*** run_cmd() ***');
let run_cmd_result = await native_app.run_cmd({cmd: cmd, return_stdout: return_stdout})
.then(function (result) {
if (result) {
console.log('Command ran');
} else {
console.log('Command did not run. Something went wrong.');
return false;
}
if (return_stdout) {
return result;
} else {
return true;
}
});
console.log('Run Command Result:', run_cmd_result);
return run_cmd_result;
}
// Updated 2022-10-27
export let run_cmd_sync = function run_cmd_sync({cmd=null, return_stdout=null}) {
console.log('*** run_cmd_sync() ***');
let run_cmd_result = native_app.run_cmd_sync({cmd: cmd, return_stdout: return_stdout});
// if (run_cmd_result) {
// console.log('Command ran');
// } else {
// console.log('Command did not run. Something went wrong.');
// // return false;
// }
// if (return_stdout) {
// return run_cmd_result;
// } else {
// return true;
// }
console.log('Run Command Result:', run_cmd_result);
return run_cmd_result;
}
// Updated 2022-05-07
export let run_osascript = async function run_osascript({cmd=null, interactive=false, language=null, flags='h', program_file=null}) {
console.log('*** run_osascript() ***');
let run_osascript_result = await native_app.run_osascript({cmd: cmd, interactive: interactive, language: language, flags: flags, program_file: program_file});
console.log(run_osascript_result);
if (run_osascript_result) {
console.log('Apple Script ran');
} else {
console.log('Apple Script did not run. Something went wrong.');
}
return run_osascript_result;
}
// Updated 2022-05-07
export let get_device_info = async function get_device_info({event_device_id}) {
console.log('*** get_device_info() ***');
console.log(event_device_id);
let get_device_info_result = await native_app.get_device_info();
console.log(get_device_info_result);
if (get_device_info_result) {
console.log('Success');
} else {
console.log('Failed? Something went wrong.');
}
return get_device_info_result;
}

View File

@@ -0,0 +1,429 @@
<script lang="ts">
import { createEventDispatcher, onMount, tick } from 'svelte';
// import { liveQuery } from "dexie";
import { ae_util } from '$lib/ae_utils/ae_utils';
import { ae_loc, ae_sess, ae_api, slct, slct_trigger } from '$lib/ae_stores';
// Ideally the Event related stores should not be imported here?
import { events_loc } from '$lib/ae_events_stores';
// import { db_events } from "$lib/db_events";
let entered_passcode: null|string = null;
let show_passcode_input: boolean = false;
let trigger: null|string = null;
const dispatch = createEventDispatcher();
onMount(() => {
console.log('** Element Mounted: ** Element Access Type');
});
$: if (entered_passcode && entered_passcode.length >= 5) {
console.log(`entered_passcode=${entered_passcode}`);
handle_check_access_type_passcode();
}
$: if (trigger && $ae_loc.access_type) {
console.log(`$ae_loc.access_type=${$ae_loc.access_type}`);
let access_checks_results = ae_util.process_permission_checks($ae_loc.access_type);
$ae_loc = {...$ae_loc, ...access_checks_results};
} else if (trigger) {
console.log(`$ae_loc.access_type=not set`);
// Send an empty string to reset the permissions. This is the same as sending 'anonymous'.
let access_checks_results = ae_util.process_permission_checks('');
$ae_loc = {...$ae_loc, ...access_checks_results};
}
function handle_check_access_type_passcode() {
console.log(`*** handle_check_access_type_passcode() *** passcode list:`, $ae_loc.site_access_code_kv);
if (entered_passcode && entered_passcode.length >= 5) {
if ($ae_loc.site_access_code_kv.super == entered_passcode) {
console.log('Super passcode matched');
window.localStorage.setItem('access_type', 'super');
$ae_loc.access_type = 'super';
} else if ($ae_loc.site_access_code_kv.manager == entered_passcode) {
console.log('Manager passcode matched');
window.localStorage.setItem('access_type', 'manager');
$ae_loc.access_type = 'manager';
} else if ($ae_loc.site_access_code_kv.administrator == entered_passcode) {
console.log('Administrator passcode matched');
window.localStorage.setItem('access_type', 'administrator');
$ae_loc.access_type = 'administrator';
} else if ($ae_loc.site_access_code_kv.trusted == entered_passcode) {
console.log('Trusted passcode matched');
window.localStorage.setItem('access_type', 'trusted');
$ae_loc.access_type = 'trusted';
} else if ($ae_loc.site_access_code_kv.public == entered_passcode) {
console.log('Public passcode matched');
window.localStorage.setItem('access_type', 'public');
$ae_loc.access_type = 'public';
} else if ($ae_loc.site_access_code_kv.authenticated == entered_passcode) {
console.log('Authenticated passcode matched');
window.localStorage.setItem('access_type', 'authenticated');
$ae_loc.access_type = 'authenticated';
} else {
console.log('Passcode does not match');
window.localStorage.setItem('access_type', 'anonymous');
$ae_loc.access_type = 'anonymous';
trigger = 'process_permission_check';
// $ae_loc = $ae_loc; // Trigger Svelte just in case
// ae_loc.set($ae_loc);
// console.log($ae_loc);
dispatch_access_type_changed();
return false;
}
entered_passcode = null;
trigger = 'process_permission_check';
// WARNING 2024-08-21: For some reason the config element does not auto show or hide when the access type changes.
if (!$ae_loc.iframe && $ae_loc.authenticated_access) {
$ae_loc.hub.show_element__access_type = true;
$ae_loc.hub.show_element__cfg = true;
} else if ($ae_loc.iframe && $ae_loc.trusted_access) {
$ae_loc.hub.show_element__access_type = true;
$ae_loc.hub.show_element__cfg = true;
} else {
$ae_loc.hub.show_element__access_type = true;
$ae_loc.hub.show_element__cfg = false;
}
dispatch_access_type_changed();
return true;
} else {
console.log('Entered passcode too short.');
// $ae_loc.access_type = null; // 'anonymous';
// dispatch_access_type_changed()
return null;
}
}
function handle_clear_access() {
// NOTE: I think it makes since to reset this to anonymous even if logged in as an admin or similar.
window.localStorage.setItem('access_type', 'anonymous');
// $ae_loc.access_type = null; // 'anonymous';
$ae_loc.access_type = 'anonymous';
trigger = 'process_permission_check';
show_passcode_input = false;
// $ae_loc = $ae_loc; // Trigger Svelte just in case
// ae_loc.set($ae_loc);
// console.log($ae_loc);
dispatch_access_type_changed();
return true;
}
function dispatch_access_type_changed() {
console.log('*** dispatch_access_type_changed() ***');
console.log(ae_util);
console.log($ae_loc);
dispatch('access_type_changed', {
access_type: $ae_loc.access_type
});
}
function dispatch_edit_mode_changed() {
console.log('*** dispatch_edit_mode_changed() ***');
console.log(ae_util);
console.log($ae_loc);
window.localStorage.setItem('edit_mode', $ae_loc.edit_mode);
dispatch('edit_mode_changed', {
edit_mode: $ae_loc.edit_mode
});
}
</script>
<section id="AE-Quick-Access-Type" class="ae_access_type bg-surface-100 text-surface-800 transition duration-300 delay-150 hover:delay-1000 hover:ease-out transition-all hover:transition-all hidden-print flex flex-col items-end gap-1">
<!-- Show list of authorized sessions and presentations for a user -->
<!-- {#if $ae_loc.access_type == 'administrator'}
{#if $events_loc.auth__kv.session}
Sessions:
<ul>
{#each Object.entries($events_loc.auth__kv.session) as [key, value]}
<li><a href="/events_pres_mgmt/session/{key}">
{key}
</a></li>
{/each}
</ul>
{/if}
{/if} -->
<div>
{#if $ae_loc.trusted_access}
{#if $ae_loc.manager_access}
{#if $ae_loc?.sync_local_config}
<button
type="button"
on:click={() => {
$ae_loc.sync_local_config = false;
$events_loc.pres_mgmt.sync_local_config = false;
$ae_loc.lock_config = false;
$events_loc.pres_mgmt.lock_config = false;
// dispatch_sync_local_config_changed();
// tick();
return false;
}}
class="btn btn-sm variant-ghost-success hover:variant-filled-success transition-all hover:transition-all *:hover:inline"
title="Syncing the local configuration with the remote configuration."
>
<span class="fas fa-sync m-1"></span>
<span class="hidden">
Sync
</span>
</button>
{:else}
<button
type="button"
on:click={() => {
$ae_loc.sync_local_config = true;
$events_loc.pres_mgmt.sync_local_config = true;
$ae_loc.lock_config = true;
$events_loc.pres_mgmt.lock_config = true;
// dispatch_sync_local_config_changed();
// tick();
return true;
}}
class="btn btn-sm variant-ghost-warning hover:variant-filled-warning transition-all hover:transition-all *:hover:inline"
title="Currently not syncing with the remote server. Re-sync the local configuration with the remote configuration?"
>
<span class="fas fa-unlink m-1"></span>
<span class="hidden">
Re-sync?
</span>
</button>
{/if}
{/if}
{#if $ae_loc.edit_mode}
<button
type="button"
on:click={() => {
$ae_loc.edit_mode = false;
dispatch_edit_mode_changed();
}}
class="btn btn-sm variant-ghost-success hover:variant-filled-success"
title="Edit mode is currently enabled. Click to disable."
>
<span class="fas fa-toggle-on mx-1"></span>
Edit Mode On
</button>
{:else}
<button
type="button"
on:click={() => {
$ae_loc.edit_mode = true;
dispatch_edit_mode_changed();
}}
class="btn btn-sm variant-ghost-warning hover:variant-filled-warning"
title="Edit mode is currently disabled. Click to enable."
>
<span class="fas fa-toggle-off mx-1"></span>
Edit Mode?
</button>
{/if}
{/if}
</div>
<div>
{#if $ae_loc.access_type && $ae_loc.access_type != 'anonymous'}
<span class="fas fa-unlock mx-1"></span>
{#if $ae_loc.access_type == 'super'}
<span class="fas fa-hat-wizard m-1"></span>
Super
{:else if $ae_loc.access_type == 'manager'}
<span class="fas fa-user-shield m-1"></span>
Manager
{:else if $ae_loc.access_type == 'administrator'}
<span class="fas fa-user-ninja m-1"></span>
Administrator
{:else if $ae_loc.access_type == 'trusted'}
<span class="fas fa-user-check m-1"></span>
Trusted Access
{:else if $ae_loc.access_type == 'public'}
Public Access
{:else if $ae_loc.access_type == 'authenticated'}
Authenticated Access
{:else if $ae_loc.access_type == 'anonymous'}
Anonymous Access
{:else}
Unknown Access
{/if}
<button
type="button"
class="btn btn-sm variant-ghost-success hover:variant-filled-success access_type_lock_btn transition-all hover:transition-all"
on:click={() => {
handle_clear_access();
}}
title="Access mode is currently enabled/unlocked. Click to exit and lock."
>
<span class="fas fa-lock mx-1"></span> Lock?
</button>
{:else}
<button
type="button"
class="btn btn-sm variant-glass-success hover:variant-filled-warning access_type_unlock_btn transition-all hover:transition-all"
on:click={async () => {
show_passcode_input = !show_passcode_input;
await tick();
document.getElementById('access_passcode_input').focus();
// element.focus({preventScroll:false});
}}
title="Anonymous public access is currently set. Access mode is disabled/locked."
>
<span class="fas fa-lock mx-1 lock_icon"></span>
<span class="fas fa-unlock mx-1 unlock_icon hidden"></span>
<span class="unlock_text">Unlock?</span>
</button>
<input
id="access_passcode_input"
bind:value={entered_passcode}
class="input w-32 transition-all"
class:hidden={!show_passcode_input}
type="text"
placeholder="Access code"
/>
<!-- <div class="current_text transition-all">{$ae_loc.access_type}</div> -->
{/if}
</div>
</section>
<style lang="postcss">
/* BEGIN: AE's Svelte Quick Access Type component */
#AE-Quick-Access-Type {
/* position: absolute; */
position: fixed;
/* position: relative; */
/* position: static; */
/* position: sticky; */
/* top: 1em; */
bottom: 1.5rem;
right: 0rem;
padding: .5rem;
/* lightyellow */
/* background-color: hsla(60,100%,90%,.30); */
/* background-color: rgba(var(--color-surface-500) / .5); */
border-top: solid thin hsla(0,0%,0%,.25);
border-left: solid thin hsla(0,0%,0%,.25);
border-bottom: solid thin hsla(0,0%,0%,.25);
border-top-left-radius: .5em;
border-bottom-left-radius: .5em;
opacity: .15;
/* opacity: 1; */
font-size: .75rem;
z-index: 5;
/* NOTE: transition when no longer hovering */
transition-property: opacity, background-color;
transition-delay: 1.25s;
transition-duration: .75s;
transition-timing-function: ease-out;
}
#AE-Quick-Access-Type:hover {
/* lightyellow */
/* background-color: hsla(60,100%,90%,.95); */
/* background-color: rgba(var(--color-surface-500) / 1); */
border-top: solid thin hsla(0,0%,0%,.95);
border-left: solid thin hsla(0,0%,0%,.95);
border-bottom: solid thin hsla(0,0%,0%,.95);
opacity: 1;
/* NOTE: transition when hover starts */
transition-property: opacity, background-color;
transition-delay: .5s;
transition-duration: .25s;
transition-timing-function: ease-in;
}
/* #Access-Type .unlock_text {
transition: width 2s, height 2s, background-color 2s, transform 2s;
} */
/* END: Svelte Access Type component */
.access_type_unlock_btn:hover .lock_icon {
display: none;
}
.access_type_unlock_btn:hover .unlock_icon {
display: initial;
}
.access_type_unlock_btn .unlock_text {
display: none;
}
.access_type_unlock_btn:hover .unlock_text {
display: initial;
/* outline: solid thin red; */
}
.ae_access_type .current_text {
display: none;
}
.ae_access_type:hover .current_text {
display: initial;
/* outline: solid thin red; */
}
</style>

View File

@@ -0,0 +1,466 @@
<script lang="ts">
// *** Import Svelte core
import { createEventDispatcher, onMount } from 'svelte';
// *** Import Aether core variables and functions
import type { key_val } from '$lib/ae_stores';
// import { api } from '$lib/api';
import { core_func } from '$lib/ae_core_functions';
// import { ae_loc, ae_sess, ae_api, ae_trig, slct, slct_trigger } from '$lib/ae_stores';
// *** Import Aether core components
// *** Import Aether module variables and functions
// *** Import Aether module components
// *** Export/Exposed variables and functions for component
export let log_lvl: number = 0;
export let trigger_patch: any = null;
export let api_cfg: key_val = {'api_crud_super_key': null};
// export let api_crud_super_key: null|string = api_cfg.api_crud_super_key;
export let object_type: string;
export let object_id: string;
export let field_name: string;
export let field_type: string = 'text'; // button, text, textarea, template (older method), select (in progress method)
export let field_value: any;
export let allow_null: boolean = false;
export let select_option_li: key_val = {};
export let val_empty_is_null: boolean = false; // This was added to help with a select option list. If the value is empty (''), it will be set to null.
export let edit_label: string = 'Edit';
export let display_inline: boolean = false;
export let display_block_edit: boolean = false;
export let textarea_cols: number = 80;
export let textarea_rows: number = 5;
// export let input_field_template: null|object = null;
export let hide_edit_btn = false;
export let outline_element = false;
export let show_crud = false;
export let btn_label = null; // '<span class="fas fa-check mx-1"></span> Save'; // PATCH
// export let show_field_name = true;
// export let show_original_value = true;
// export let trim_string = false;
// export let remove_breaks = false;
export let class_li: string = '';
// *** Set initial variables
let ae_promises: key_val = {}; // Promise<any>;
let patch_result: null|Promise<any>|key_val|string;
let original_field_value = field_value;
const dispatch = createEventDispatcher();
onMount(() => {
if (log_lvl) {
console.log(`Element AE CRUD: Object Type: ${object_type}; Object ID: ${object_id}; Field Name: ${field_name}; Field Value: ${field_value} (Original: ${original_field_value})`);
// ; Super Key: ${api_crud_super_key}
}
});
$: if (trigger_patch == true) {
console.log('AE CRUD: Patch triggered!');
trigger_patch = null;
handle_obj_field_patch(field_value);
}
// Updated 2024-03-22
async function handle_obj_field_patch(new_field_value: any) {
console.log('*** handle_obj_field_patch() ***');
patch_result = null;
// This was added to help with a select option list. If the value is empty (''), it will be set to null.
if (val_empty_is_null && new_field_value == '') {
new_field_value = null;
}
// NOTE: Is this needed? The field_name, field_value, and fields parameters for update_ae_obj_id_crud() already take care of the data portion. They are added to data_list object as part of the JSON request.
// NOTE: Currently this only handles one field and value at a time. This may need to be changed in the future to use the "fields" parameter as well.
// let patch_data = {}
// if (remove_breaks) {
// patch_data['field_value'] = field_value.replace(/(\r\n|\n|\r)/gm, "");
// } else {
// patch_data['field_value'] = field_value;
// }
// patch_data[field_name] = field_value;
// console.log(patch_data);
// let params = {};
ae_promises.api_update__ae_obj = core_func.handle_update_ae_obj_id_crud({
api_cfg: api_cfg,
object_type: object_type,
object_id: object_id,
field_name: field_name,
new_field_value: new_field_value,
params: {},
try_cache: false,
log_lvl: 0
})
.then(function (results) {
console.log('Field PATCH Promise', results);
if (results) {
console.log(`Patched - Field Name: ${field_name} with new Field Value: ${new_field_value}; Original Field Value: ${original_field_value}`);
patch_result = 'PATCH complete';
original_field_value = new_field_value;
} else {
console.log(`Not Patched - Field Name: ${field_name} with new Field Value: ${new_field_value}; Original Field Value: ${original_field_value}`);
patch_result = 'PATCH failed';
return false;
}
return true;
})
.catch(function (error) {
console.log('Something went wrong patching the record.');
console.log(error);
return false;
})
.finally(function () {
console.log('Field PATCH Promise finally');
// This dispatch() must be under "finally".
dispatch(
'ae_crud_updated',
{
'type': object_type,
'id': object_id,
'field_name': field_name,
'field_value': new_field_value,
'original_value': original_field_value,
}
);
});
return ae_promises.api_update__ae_obj;
}
</script>
<div
class="{class_li} ae_crud"
class:show_crud
class:display_inline
class:outline_element
>
<span class="field_viewing_wrapper">
<slot></slot>
<button
class="btn btn-sm variant-soft-warning hover:variant-ghost-error field_show_btn"
class:hide_edit_btn
class:show_crud
on:dblclick={() => {
show_crud = true;
}}
title="Double click to edit"
>
<span class="fas fa-edit"></span>
</button>
</span>
<div
class:display_block_edit
class="field_editing_wrapper min-w-content w-100 max-w-full"
>
<!-- <span class="grow flex flex-row items-center justify-between"> -->
<!-- <span class="">
{edit_label}
</span> -->
<button
class="btn btn-md variant-glass-tertiary hover:variant-ghost-tertiary m-1 transition-all"
class:show_crud
on:click={() => {
show_crud = false;
}}
title="Close field editing"
>
<span class="fas fa-window-close"></span>
<span class="hidden md:inline">Close</span>
</button>
<!-- </span> -->
<span
class="field_value grow min-w-content max-w-full"
class:show_crud
>
{#if field_type == 'template'}
<!-- <Element_input_v2 {...input_field_template} bind:value={field_value} /> -->
{:else if field_type == 'button'}
<!-- <input type="button" bind:value={field_value}> -->
{field_value}
{:else if field_type == 'select'}
<select
bind:value={field_value}
class="select"
>
{#if select_option_li && Object.keys(select_option_li).length == 0}
<option value="">-- not set --</option>
{:else if select_option_li && Object.keys(select_option_li).length > 0}
{#each Object.keys(select_option_li) as option}
<option value={option}>{select_option_li[option]}</option>
{/each}
{:else}
<option value="">-- no list --</option>
{/if}
</select>
{:else if field_type == 'text'}
<input
bind:value={field_value}
class="input min-w-64 w-96 max-w-full"
>
{:else if field_type == 'textarea'}
<textarea
bind:value={field_value}
cols={textarea_cols}
rows={textarea_rows}
class="textarea"
></textarea>
{:else}
<input
bind:value={field_value}
class="input w-fit"
>
{/if}
{#if allow_null}
<button
class="btn btn-sm variant-soft-warning hover:variant-ghost-warning m-1"
on:click={() => {
field_value = null;
}}
title="Set value to NULL"
>
&Oslash;
NULL
</button>
{/if}
</span>
<button
class="btn btn-lg variant-glass-primary hover:variant-ghost-primary m-1"
class:show_crud
disabled={field_value == original_field_value}
on:click={async () => {
handle_obj_field_patch(field_value);
}}
title="Save new field value"
>
{#if field_value == original_field_value}
{#if (btn_label)}
{@html btn_label}
{:else}
<span class="fas fa-check mx-1"></span>
<span>Save</span>
{/if}
<!-- <span>{patch_result}</span> -->
{:else}
{#if (btn_label)}
{@html btn_label}
{:else}
<span class="fas fa-save mx-1"></span>
<span>Save?</span>
{/if}
{/if}
</button>
<div class="field_patch_result" class:show_crud>
{#await ae_promises.api_update__ae_obj}
<span class="fas fa-spinner fa-spin mx-1"></span>
<span>Processing...</span>
{:then}
{#if patch_result}
<span class="fas fa-check mx-1"></span>
<span>{patch_result}</span>
{:else}
<!-- <div>Nothing to show yet...</div> -->
{/if}
{/await}
</div>
</div>
</div>
<style>
/* .ae_crud .field_editing_wrapper {
font-size: 1em;
} */
/* BEGIN: Svelte CRUD (update) component */
/* .ae_crud {
margin: 0;
padding: 0;
} */
.ae_crud.display_inline {
/* outline: solid thin red; */
display: inline;
}
.ae_crud.show_crud .field_viewing_wrapper .field_show_btn {
display: none;
}
.ae_crud.outline_element .field_viewing_wrapper {
outline: dotted thin hsla(0,50%,50%,0);
transition: outline 3s 1s;
}
.ae_crud.outline_element .field_viewing_wrapper:hover {
outline: dashed thin hsla(0,50%,50%,.9);
transition: outline 1s .5s;
}
.ae_crud .field_viewing_wrapper .field_show_btn.hide_edit_btn {
display: none;
}
.ae_crud .field_viewing_wrapper .field_show_btn {
margin: 0;
padding: 0;
/* color: hsla(0,0%,50%,.8); */
opacity: .25;
/* NOTE: transition when hover ends */
transition-property: opacity, background-color, border-color, color, height, width;
transition-delay: 1.00s; /* no delay */
transition-duration: .55s;
transition-timing-function: linear;
}
.ae_crud .field_viewing_wrapper:hover .field_show_btn {
/* outline: solid thin hsla(0,50%,50%,.9); */
/* color: hsla(0,50%,50%,.9); */
opacity: 1;
/* NOTE: transition when hover starts */
transition-property: opacity, background-color, border-color, color, height, width;
transition-delay: .25s; /* no delay */
transition-duration: .50s;
transition-timing-function: linear;
}
.ae_crud .field_editing_wrapper {
/* outline: dashed thin pink; */
display: none;
/* position: relative; */
/* contain: layout; */
/* contain: size; */
/* contain: none; */
contain: content;
box-shadow: .5em .5em .75em .75em hsla(0,0%,0%,0.5);
/* color: hsla(0,0%,50%,.8); */
background-color: hsla(0,0%,50%,.5);
border: dashed thin transparent;
/* font-size: 1em; */
/* line-height: 1em; */
height: 1em;
width: 1em;
/* NOTE: transition when hover ends */
transition-property: background-color, border-color, color, height, width;
transition-delay: .75s; /* short delay */
transition-duration: .50s;
transition-timing-function: linear;
}
.ae_crud.show_crud .field_editing_wrapper {
/* display: initial; */
display: block;
contain: content;
/* background-color: yellow; */
background-color: hsla(60,50%,80%,.95);
border: solid thin hsla(0,50%,50%,.50);
border-radius: .5em;
height: auto;
/* height: 100%; */
max-height: 100%;
min-width: fit-content;
width: auto;
max-width: 100%;
/* NOTE: transition when hover starts */
transition-property: background-color, border-color, height, width;
transition-delay: .25s; /* no delay */
transition-duration: .25s;
transition-timing-function: linear;
/* position: absolute; */
/* position: fixed; */
/* position: relative; */
/* top: 1em; */
/* left: 1em; */
/* right: 1em; */
/* bottom: 1em; */
z-index: 1;
padding: .5em;
}
.ae_crud.show_crud.display_inline .field_editing_wrapper {
/* display: block; */
display: inline-block;
/* display: inline; */
box-shadow: initial;
background-color: hsla(60,50%,80%,.3);
padding: .25em;
position: initial;
z-index: 0;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
gap: .5em;
width: 30%;
}
.ae_crud.show_crud.display_inline .field_editing_wrapper.display_block_edit {
/* display: block; */
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: .5em;
flex-grow: 1;
height: auto;
width: 100%;
}
.ae_crud textarea {
height: auto;
}
/* END: Svelte CRUD (update) component */
</style>

View File

@@ -0,0 +1,358 @@
<script lang="ts">
import { createEventDispatcher, onMount } from 'svelte';
import { RadioGroup, RadioItem } from '@skeletonlabs/skeleton';
import { ae_util } from '$lib/ae_utils/ae_utils';
import { ae_loc, ae_sess, ae_api, slct, slct_trigger } from '$lib/ae_stores';
let notes: null|string = null;
let all: boolean = false;
// export let theme_mode: null|string = null;
export let set_theme_mode: null|boolean = null;
// export let theme_name: null|string = null;
export let set_theme_name: null|boolean = null;
const dispatch = createEventDispatcher();
onMount(() => {
console.log('** Element Mounted: ** Element App Config');
if (set_theme_mode) {
$slct_trigger = 'set_theme_mode';
}
if (set_theme_name) {
$slct_trigger = 'set_theme_name';
}
});
// $: if ($slct_trigger == 'set_theme_mode' && $ae_loc?.hub?.theme_mode) {
// console.log(`$ae_loc.hub.theme_mode=${$ae_loc?.hub?.theme_mode}`);
// $slct_trigger = null;
// if ($ae_loc.hub.theme_mode == 'light') {
// document.documentElement.classList.remove('dark');
// document.documentElement.classList.add('light');
// } else if ($ae_loc.hub.theme_mode == 'dark') {
// document.documentElement.classList.remove('light');
// document.documentElement.classList.add('dark');
// }
// }
// $: if ($slct_trigger == 'set_theme_name' && $ae_loc?.hub?.theme_name) {
// console.log(`$ae_loc?.hub?.theme_name=${$ae_loc?.hub?.theme_name}`);
// $slct_trigger = null;
// // Update the body attribute named "data-theme" to the current theme name.
// document.body.setAttribute('data-theme', $ae_loc?.hub?.theme_name);
// }
// $: if (entered_passcode && entered_passcode.length >= 5) {
// console.log(`entered_passcode=${entered_passcode}`);
// handle_check_access_type_passcode();
// }
// $: if (trigger && $ae_loc.access_type) {
// console.log(`$ae_loc.access_type=${$ae_loc.access_type}`);
// let access_checks_results = ae_util.process_permission_checks($ae_loc.access_type);
// $ae_loc = {...$ae_loc, ...access_checks_results};
// } else if (trigger) {
// console.log(`$ae_loc.access_type=not set`);
// // Send an empty string to reset the permissions. This is the same as sending 'anonymous'.
// let access_checks_results = ae_util.process_permission_checks('');
// $ae_loc = {...$ae_loc, ...access_checks_results};
// }
function handle_something() {
// console.log('*** handle_something() ***');
}
function handle_clear_storage(item: null|string) {
// console.log('*** handle_clear_storage() ***');
// window.localStorage.setItem('access_type', 'anonymous');
// return true;
}
function dispatch_something_changed() {
console.log('*** dispatch_something_changed() ***');
console.log(ae_util);
console.log($ae_loc);
dispatch('access_type_changed', {
access_type: $ae_loc.access_type
});
}
</script>
<!-- transition duration-500 delay-1000 hover:duration-500 hover:delay-1000 hover:transition-all -->
<section id="AE-App-Cfg" class="ae_app_cfg bg-surface-100 text-surface-800 transition hover:transition-all hidden-print">
<div
class="ae_cfg_content text-xs space-y-4 my-4"
class:hidden={!$ae_loc.hub.show_element__cfg_detail}
data-sveltekit-preload-data="false"
>
<section class="space-y-2">
<div>
<h2 class="strong">Access Type:</h2>
<div>
{#if $ae_loc.access_type && $ae_loc.access_type != 'anonymous'}
{#if $ae_loc.access_type == 'super'}
<span class="fas fa-secret mx-1"></span> Super Access
{:else if $ae_loc.access_type == 'manager'}
<span class="fas fa-user-shield mx-1"></span> Manager Access
{:else if $ae_loc.access_type == 'administrator'}
<span class="fas fa-user-ninja mx-1"></span> Administrator Access
{:else if $ae_loc.access_type == 'trusted'}
<span class="fas fa-user-nurse mx-1"></span> Trusted Access
{:else if $ae_loc.access_type == 'authenticated'}
<span class="fas fa-user-friends mx-1"></span> Authenticated Access
{:else if $ae_loc.access_type == 'anonymous'}
<span class="fas fa-users mx-1"></span> Anonymous Access
{:else}
<span class="fas fa-unlock mx-1"></span> Unknown Access
{/if}
<!-- <button
class="btn btn-sm variant-glass-secondary access_type_lock_btn hover:transition-all"
on:click={() => {
handle_clear_access();
}}
title="Access mode is currently enabled/unlocked. Click to exit and lock."
>
<span class="fas fa-lock mx-1"></span> Lock
</button> -->
{:else}
Not logged in
{/if}
</section>
<!-- END: Access Type -->
<section class="space-y-2">
<h2 class="strong">Theme:</h2>
<div>
<!-- Light/Dark Theme: -->
<RadioGroup
active="variant-glass-success"
hover="hover:variant-ringed-surface"
>
<RadioItem
on:change={() => {
$slct_trigger = 'set_theme_mode';
}}
bind:group={$ae_loc.hub.theme_mode}
name="theme_light"
value={'light'}
>
Light
</RadioItem>
<RadioItem
on:change={() => {
$slct_trigger = 'set_theme_mode';
}}
bind:group={$ae_loc.hub.theme_mode}
name="theme_dark"
value={'dark'}
>
Dark
</RadioItem>
</RadioGroup>
</div>
<div>
<!-- Theme Name: -->
<select
on:change={() => {
$slct_trigger = 'set_theme_name';
}}
bind:value={$ae_loc.hub.theme_name}
class="select"
title="Theme name"
>
<option value="">-- None --</option>
<option value="gold-nouveau">Gold Nouveau</option>
<option value="hamlindigo">Hamlindigo</option>
<option value="modern">Modern</option>
<option value="rocket">Rocket</option>
<option value="wintry">Wintry</option>
</select>
</div>
</section>
<!-- END: Theme -->
<section class="space-y-2">
<h2 class="strong">Utilities:</h2>
<a
class="btn btn-sm variant-glass-secondary"
href="/hosted_files"
>
<span class="fas fa-code mx-1"></span>
Util: Convert Videos
</a>
{#if $ae_loc.iframe}
<a
class="btn btn-sm variant-glass-secondary"
href="/?iframe=false"
>
<span class="fas fa-code mx-1"></span>
Exit iframe Mode
</a>
{:else}
<a
class="btn btn-sm variant-glass-secondary"
href="/?iframe=true"
>
<span class="fas fa-code mx-1"></span>
Use iframe Mode
</a>
{/if}
<div>
<button
class="btn btn-sm variant-glass-warning"
title="Reload and clear the page cache"
on:click={() => {
// $ae_loc.
window.location.reload(true);
}}
>
<span class="fas fa-sync mx-1"></span>
Reload
&amp;
<span class="fas fa-trash mx-1"></span>
Clear Cache
</button>
<button
class="btn btn-sm variant-glass-warning"
title="Clear the browser storage for this page"
on:click={() => {
if (!confirm('Are you sure you want to clear the local and session storage?')) {
return false;
}
// Clear the local and session storage
localStorage.clear();
sessionStorage.clear();
// Clear Indexed DB as well
indexedDB.deleteDatabase('ae_core_db');
indexedDB.deleteDatabase('ae_events_db');
window.location.reload();
// alert('Local and Session Storage cleared and Indexed DBs deleted. You will probably want to refresh the page.');
}}
>
<span class="fas fa-eraser mx-1"></span>
Clear Storage &amp; DB
</button>
</div>
</section>
<!-- END: Utilities -->
</div>
<button
class="btn btn-sm variant-glass-warning ae_cfg_btn hover:transition-all"
on:click={() => {
$ae_loc.hub.show_element__cfg_detail = !$ae_loc.hub.show_element__cfg_detail;
}}
>
<span class="fas fa-cog mx-1"></span>
<span class="cfg_text">Config</span>
</button>
</section>
<style lang="postcss">
/* BEGIN: AE's Svelte App Config component */
#AE-App-Cfg {
/* position: absolute; */
position: fixed;
/* position: relative; */
/* position: static; */
/* position: sticky; */
/* top: 1em; */
bottom: 1.5rem;
left: 0rem;
padding: .5rem;
/* lightyellow */
/* background-color: hsla(60,100%,90%,.30); */
/* background-color: rgba(var(--color-surface-500) / .95); */
border-top: solid thin hsla(0,0%,0%,.5);
border-right: solid thin hsla(0,0%,0%,.5);
border-bottom: solid thin hsla(0,0%,0%,.5);
border-top-right-radius: .5em;
border-bottom-right-radius: .5em;
opacity: .15;
/* opacity: 1; */
font-size: .75rem;
z-index: 5;
/* NOTE: transition when no longer hovering */
transition-property: opacity, background-color;
transition-delay: 1.25s;
transition-duration: .5s;
transition-timing-function: ease-out;
}
#AE-App-Cfg:hover {
/* lightyellow */
/* background-color: hsla(60,100%,90%,.95); */
/* background-color: rgba(var(--color-surface-100) / 1); */
/* color: black; */
border-top: solid thin hsla(0,0%,0%,.95);
border-right: solid thin hsla(0,0%,0%,.95);
border-bottom: solid thin hsla(0,0%,0%,.95);
opacity: 1;
/* NOTE: transition when hover starts */
transition-property: opacity, background-color;
transition-delay: .5s;
transition-duration: .10s;
transition-timing-function: ease-in;
}
.ae_cfg_btn .cfg_text {
display: none;
}
.ae_cfg_btn:hover .cfg_text {
display: initial;
/* outline: solid thin red; */
}
.access_type .current_text {
display: none;
}
.access_type:hover .current_text {
display: initial;
/* outline: solid thin red; */
}
/* END: AE's Svelte App Config component */
</style>

View File

@@ -0,0 +1,804 @@
<script lang="ts">
import { onMount } from 'svelte';
import { api } from '$lib/api';
import { ae_loc, ae_sess, ae_api, slct, slct_trigger, ae_trig } from '$lib/ae_stores';
import { ae_util } from '$lib/ae_utils/ae_utils';
import type { key_val } from '$lib/ae_stores';
export let expire_minutes: number = 10;
export let mount_reload_sec: number = 0;
export let ds_code: string;
export let ds_name: null|string = null;
export let ds_type: string = 'text';
export let for_type: null|string = null;
export let for_id: null|string = null;
console.log(`ae_e_data_store ${ds_code} for_type=${for_type} for_id=${for_id} account_id=${$ae_loc.account_id}`);
// export let store: string = 'local';
export let display: string = 'block'; // Avoid; Use class list instead
export let class_li: string = ''; // : string[] = [];
export let try_cache: boolean = true;
export let hide: boolean = false; // Hide the entire element
export let show_edit: boolean = false;
export let show_edit_btn: boolean = true;
export let show_view: boolean = true;
// export let show_delete_btn: boolean = false;
export let ds_loaded: boolean = false;
export let debug: boolean = false;
let ae_promises: key_val = {}; // Promise<any>;
let ds_get_results: Promise<any>|key_val;
let ds_loading_status: string = 'starting...';
let ds_submit_results: Promise<any>|key_val;
let val_json: key_val;
let val_html: key_val;
let val_md: key_val;
export let val_sql: null|key_val = null;
let val_text: string;
let ds_code_obj =
{
id: null,
account_id: null,
code: ds_code,
name: ds_name,
type: ds_type,
for_type: null, // for_type
for_id: null, // for_id
access_read: null, // 'super', 'manager', 'administrator', 'trusted', 'authenticated', 'anonymous'
access_write: null, // 'super', 'manager', 'administrator', 'trusted', 'authenticated', 'anonymous'
access_delete: null, // 'super', 'manager', 'administrator', 'trusted', 'authenticated', 'anonymous'
html: null,
json: null,
md: null,
text: null,
updated_on: null,
chk_account_id: null,
};
let ae_ds_tmp: key_val;
if (browser && localStorage.getItem(`ae_ds__${ds_code}`)) {
ae_ds_tmp = JSON.parse(localStorage.getItem(`ae_ds__${ds_code}`));
} else {
ae_ds_tmp = ds_code_obj;
}
// console.log(`ae_e_data_store cached: ${ds_code} = `, ae_ds_tmp);
console.log(`ae_e_data_store cached: ${ds_code} account_id=${$ae_loc.account_id}`);
if (!ae_ds_tmp || !ae_ds_tmp.id) {
ds_loading_status = '-- loading --';
} else {
// ae_ds_loc.set(ae_ds_tmp);
}
$ae_sess.ds.submit_status = null;
$ae_sess.ds.create_status = null;
$ae_sess.ds.update_status = null;
let trigger: null|string = null;
// $: if (ae_ds_tmp) {
// console.log(`ae_e_data_store ae_ds_loc = `, ae_ds_tmp);
// }
import { browser } from '$app/environment';
let ae_ds_loc_test: any;
if (browser) {
console.log('ae_e_data_store Browser detected.');
ae_ds_loc_test = JSON.parse(localStorage.getItem(`ae_ds__${ds_code}`));
console.log(`ae_e_data_store ae_ds_loc_test = `, ae_ds_loc_test);
// ae_ds_tmp = {id: null};
// ae_ds_tmp = ae_ds_loc_test;
} else {
console.log('ae_e_data_store Browser not detected.');
}
// This is a quick check to make sure the data store is not stale. If it is, then we need to trigger a reload.
if (browser && ae_ds_tmp && ae_ds_tmp.loaded_on && ae_ds_tmp.chk_account_id == $ae_loc.account_id) {
console.log(`ae_e_data_store ${ds_code} loaded_on: ${ae_ds_tmp.loaded_on}`);
let loaded_on = new Date(ae_ds_tmp.loaded_on);
let now = new Date();
let diff = now.getTime() - loaded_on.getTime();
let diff_minutes = diff / (1000 * 60);
if (diff_minutes > expire_minutes) {
console.log(`ae_e_data_store: Data Store ${ds_code} stale. Last loaded on: ${loaded_on.toISOString()}`);
// Wait for random number of milliseconds to avoid all data stores being reloaded at the same time.
let random_ms = Math.floor(Math.random() * 500);
console.log(`ae_e_data_store: Random number of milliseconds: ${random_ms}`);
setTimeout(() => {
trigger = 'load__ds__code';
}, random_ms);
}
} else if (browser) {
console.log('ae_e_data_store: No loaded_on date found and or the account_id check failed. Need to trigger reload.');
trigger = 'load__ds__code';
}
// This is a secondary check... The account_id should either be null or match the current account_id.
if (!ae_ds_tmp || !ae_ds_tmp.account_id === null || $ae_loc.account_id == $ae_loc.account_id) {
trigger = 'load__ds__code';
}
onMount(() => {
console.log('Element: Data Store element_data_store.svelte');
// console.log('ae_ MOUNTED Browser detected.');
if (mount_reload_sec) {
// Wait for random number of milliseconds to avoid all data stores being reloaded at the same time.
let random_ms = Math.floor(Math.random() * mount_reload_sec * 1000);
console.log(`ae_e_data_store: Random number of milliseconds: ${random_ms}`);
setTimeout(() => {
trigger = 'load__ds__code';
}, random_ms);
}
});
// let ds_code_li = {}; //: key_val; // = ae_loc_tmp.ds;
// console.log(`ae_ ds_code_li = `, ds_code_li);
$: if (trigger == 'load__ds__code' && ds_code && ds_type) {
console.log(`ae_e_data_store: ae_ load__ds__code: ${ds_code} ds_type=${ds_type} for_type=${for_type} for_id=${for_id} ${try_cache}`);
trigger = null;
load_data_store({
code: ds_code,
type: ds_type,
for_type: for_type,
for_id: for_id,
try_cache: try_cache
});
}
async function load_data_store(
{
code,
type='text',
for_type=null,
for_id=null,
try_cache=true
}: {
code: string,
type: string,
for_type: string|null,
for_id: string|null,
try_cache: boolean
}
) {
// let ds_code_val = await api.get_data_store_obj_w_code({
ds_get_results = api.get_data_store_obj_w_code({
api_cfg: $ae_api,
data_store_code: code,
data_type: type,
log_lvl: 0
})
.then( function (ds_results) {
// console.log(`ae_ Data Store ${code} = `, ds_results);
if (ds_results) {
console.log(`ae_e_data_store: Got a result for code ${code}`);
if (!ds_results.data_store_id_random) {
console.log('Something went wrong? No data store ID found.');
return false;
}
ds_loaded = true;
// Set the loaded_on datetime to the current time for reference later. This will be used to determine if the data store is stale.
ae_ds_tmp.loaded_on = new Date().toISOString();
// Set the chk_account_id as a backup check to make sure the data store belongs to the account for the current site. This should not be needed, but here we are...
ae_ds_tmp.chk_account_id = $ae_loc.account_id;
ae_ds_tmp.id = ds_results.data_store_id_random;
ae_ds_tmp.account_id = ds_results.account_id_random;
ae_ds_tmp.code = ds_results.code; // This will overwrite whatever was passed in.
ae_ds_tmp.name = ds_results.name;
ae_ds_tmp.type = ds_results.type; // This will overwrite whatever was passed in.
if (type == 'html') {
ae_ds_tmp.html = ds_results.text;
val_html = ds_results.text;
return ds_results.html;
} else if (type == 'json') {
ae_ds_tmp.json = ds_results.json;
val_json = ds_results.json;
return ds_results.json;
} else if (type == 'md') {
ae_ds_tmp.text = ds_results.text;
val_md = ds_results.text;
return ds_results.text;
} else if (type == 'sql') {
ae_ds_tmp.text = ds_results.text;
val_sql = ds_results.text;
return ds_results.text;
} else {
ae_ds_tmp.text = ds_results.text;
val_text = ds_results.text;
return ds_results.text;
}
} else {
ds_loaded = false;
ds_loading_status = '-- not found --';
}
})
.catch(function (error) {
console.log(`Something went wrong. for code ${code}`);
console.log(error);
ds_loading_status = '-- error --';
return false;
});
// .finally(function (ds_val_result) {
// // console.log(`ae_ ds_code_val = `, ds_val_result);
// // ae_ds_loc.set(ds_val_result);
// // localStorage.setItem(ds_code, ds_val_result);
// // sessionStorage.setItem(ds_code, ds_val_result);
// // return ds_val_result;
// });
// console.log(`ae_ ds_code_val = `, ds_code_val);
}
async function handle_submit_form(event: any) {
// console.log('*** handle_submit_form() ***');
$ae_sess.ds.submit_status = 'processing';
// Data in
let form_data = new FormData(event.target);
// console.log(form_data);
let data_store_di: key_val = ae_util.extract_prefixed_form_data({prefix: null, form_data: form_data, trim_values: true, bool_tf_str: true, log_lvl: 0});
// console.log(data_store_di);
// Data out
let data_store_do: key_val = {};
if (typeof data_store_di.ds_id_random !== 'undefined') {
data_store_do['data_store_id_random'] = data_store_di.ds_id_random;
}
// if (!$slct.data_store_id) {
if (!ae_ds_tmp.id) {
data_store_do['account_id_random'] = $ae_loc.account_id;
}
if (typeof data_store_di.ds_account_id !== 'undefined' && data_store_di.ds_account_id && data_store_di.ds_use_account_id) {
data_store_do['account_id_random'] = data_store_di.ds_account_id;
} else if (data_store_di.ds_use_account_id && $ae_loc.account_id) {
data_store_do['account_id_random'] = $ae_loc.account_id;
} else {
data_store_do['account_id_random'] = null;
}
if (typeof data_store_di.ds_code !== 'undefined') {
data_store_do['code'] = data_store_di.ds_code;
} else {
data_store_do['code'] = ds_code;
}
if (typeof data_store_di.ds_name !== 'undefined') {
data_store_do['name'] = data_store_di.ds_name;
} else {
data_store_do['name'] = ds_name;
}
if (typeof data_store_di.ds_type !== 'undefined') {
data_store_do['type'] = data_store_di.ds_type;
} else {
data_store_do['type'] = ds_type;
}
if (typeof data_store_di.ds_for_type !== 'undefined' && data_store_di.ds_for_type) {
data_store_do['for_type'] = data_store_di.ds_for_type;
} else {
data_store_do['for_type'] = null;
}
if (typeof data_store_di.ds_for_id !== 'undefined' && data_store_di.ds_for_id) {
data_store_do['for_id_random'] = data_store_di.ds_for_id;
} else {
data_store_do['for_id_random'] = null;
}
if (typeof data_store_di.ds_access_read !== 'undefined') {
data_store_do['access_read'] = data_store_di.ds_access_read;
}
if (typeof data_store_di.ds_access_write !== 'undefined') {
data_store_do['access_write'] = data_store_di.ds_access_write;
}
if (typeof data_store_di.ds_access_delete !== 'undefined') {
data_store_do['access_delete'] = data_store_di.ds_access_delete;
}
if (typeof data_store_di.ds_value !== 'undefined') {
if (data_store_di.ds_type == 'html') {
data_store_do['text'] = data_store_di.ds_value;
} else if (data_store_di.ds_type == 'json') {
data_store_do['json'] = data_store_di.ds_value;
} else if (data_store_di.ds_type == 'md') {
data_store_do['text'] = data_store_di.ds_value;
} else if (data_store_di.ds_type == 'sql') {
data_store_do['text'] = data_store_di.ds_value;
} else {
data_store_do['text'] = data_store_di.ds_value;
}
}
if (typeof data_store_di.ds_enable !== 'undefined') {
data_store_do['enable'] = data_store_di.ds_enable;
} else {
data_store_do['enable'] = true;
}
console.log(data_store_do);
if (!ae_ds_tmp.id) {
// Create
console.log(`ae_ Data Store Create:`, data_store_do);
ds_submit_results = handle_create__data_store({
obj_type: 'data_store',
data: data_store_do
})
.then( function (ds_results) {
console.log(`ae_ Data Store Create Results:`, ds_results);
if (ds_results) {
ae_ds_tmp.id = ds_results.data_store_id_random;
ae_ds_tmp.updated_on = ds_results.updated_on;
}
return ds_results;
})
.finally(function (ds_val_result) {
console.log(`ae_ ds_val_result = `, ds_val_result);
trigger = 'load__ds__code';
$ae_sess.ds.submit_status = 'created';
});
} else {
// Update
console.log(`ae_ Data Store Update:`, data_store_do);
ds_submit_results = handle_update__data_store({
obj_type: 'data_store',
obj_id: ae_ds_tmp.id,
data: data_store_do
})
.then( function (ds_results) {
console.log(`ae_ Data Store Update Results:`, ds_results);
if (ds_results) {
ae_ds_tmp.updated_on = ds_results.updated_on;
}
return ds_results;
// })
// .finally(function (ds_val_result) {
// // console.log(`ae_ ds_code_val = `, ds_val_result);
})
.finally(function () {
// console.log(`ae_ ds_val_result = `, ds_val_result);
console.log(`ae_ load__ds__code: ${ds_code} ${ds_type} ${for_type} ${for_id} ${try_cache}`);
trigger = 'load__ds__code';
$ae_sess.ds.submit_status = 'updated';
});
}
}
async function handle_create__data_store({
obj_type,
data
}) {
console.log('*** handle_create__data_store() ***');
$ae_sess.ds.create_status = 'starting';
ae_promises.api_create__data_store_obj = api.create_ae_obj_crud({
api_cfg: $ae_api,
obj_type: obj_type,
fields: data,
key: $ae_api.api_crud_super_key,
log_lvl: 1
})
.then(async function (create__obj_result) {
if (!create__obj_result) {
console.log('The result was null or false.');
return false;
}
return create__obj_result;
})
.catch(function (error) {
console.log('Something went wrong.');
console.log(error);
return false;
})
.finally(function (create__obj_result) {
$ae_sess.ds.create_status = 'finished';
return create__obj_result;
});
return ae_promises.api_create__data_store_obj;
}
async function handle_update__data_store({
obj_type,
obj_id,
data
}) {
console.log('*** handle_update__data_store() ***');
$ae_sess.ds.update_status = 'starting';
ae_promises.update__data_store_obj = api.update_ae_obj_id_crud({
api_cfg: $ae_api,
obj_type: obj_type,
obj_id: obj_id,
fields: data,
key: $ae_api.api_crud_super_key,
log_lvl: 1
})
.then(async function (update__obj_result) {
if (!update__obj_result) {
console.log('The result was null or false.');
return false;
}
return update__obj_result;
})
.catch(function (error) {
console.log('Something went wrong.');
console.log(error);
return false;
})
.finally(function (update__obj_result) {
$ae_sess.ds.update_status = 'finished';
return update__obj_result;
})
return ae_promises.update__data_store_obj;
}
</script>
<div
class="ae__elem__data_store relative {class_li}"
class:hide={hide}
>
{#if ae_ds_tmp}
{#if debug || $ae_loc.debug == 'debug'}
<pre>
id: {ae_ds_tmp.id},
code: {ae_ds_tmp.code},
type: {ae_ds_tmp.type},
for_type: {ae_ds_tmp.for_type},
for_id: {ae_ds_tmp.for_id},
access_read: {ae_ds_tmp.access_read},
access_write: {ae_ds_tmp.access_write},
access_delete: {ae_ds_tmp.access_delete},
name: {ae_ds_tmp.name},
html: {ae_ds_tmp.html},
json: {ae_ds_tmp.json},
md: {ae_ds_tmp.md},
text: {ae_ds_tmp.text},
updated_on: {ae_ds_tmp.updated_on},
</pre>
{/if}
{#if show_edit}
<section class="edit z-50">
<form
class="ae__elem__data_store__form"
on:submit|preventDefault={handle_submit_form}
>
<input
type="hidden"
name="ds_id_random"
value={ae_ds_tmp.id}
/>
{#if $ae_loc.trusted_access}
<label for="ds_use_account_id" class="label text-xs inline">Use Account ID
<input
type="checkbox"
name="ds_use_account_id"
class="checkbox"
value="true"
checked={ae_ds_tmp.account_id ? true : false}
/>
</label>
{/if}
{#if $ae_loc.manager_access}
<input
type="text"
name="ds_account_id"
class="input max-w-48 text-xs"
placeholder="Account ID"
value={ae_ds_tmp.account_id}
/>
<input
type="text"
name="ds_code"
class="input text-xs"
placeholder="Data store code"
value={ae_ds_tmp.code}
required
/>
{/if}
{#if $ae_loc.trusted_access}
<input
type="text"
name="ds_name"
class="input text-xs"
placeholder="Data store name"
value={ae_ds_tmp.name}
required
/>
{/if}
{#if $ae_loc.manager_access}
<input
type="text"
name="ds_type"
class="input max-w-48 text-xs"
placeholder="Data store type (html, json, md, sql, text)"
value={ae_ds_tmp.type}
required
/>
<input
type="text"
name="ds_for_type"
class="input max-w-48 text-xs"
placeholder="Data store For Type"
value={ae_ds_tmp.for_type}
/>
<input
type="text"
name="ds_for_id"
class="input max-w-48 text-xs"
placeholder="Data store For ID"
value={ae_ds_tmp.for_id}
/>
<input
type="text"
name="ds_access_read"
class="input max-w-48 text-xs"
placeholder="Access read"
value={ae_ds_tmp.access_read}
/>
<input
type="text"
name="ds_access_write"
class="input max-w-48 text-xs"
placeholder="Access write"
value={ae_ds_tmp.access_write}
/>
<input
type="text"
name="ds_access_delete"
class="input max-w-48 text-xs"
placeholder="Access delete"
value={ae_ds_tmp.access_delete}
/>
{:else}
Code: {ae_ds_tmp.code}
<!-- Name: {ae_ds_tmp.name} -->
Type: {ae_ds_tmp.type}
{/if}
<!-- Handle HTML type -->
{#if ae_ds_tmp.type == 'html' || ae_ds_tmp.type == null}
<textarea
name="ds_value"
class="textarea type_html font-mono text-sm"
cols="75"
rows="25"
placeholder="Enter the HTML here"
>{ae_ds_tmp.type == 'html' && ae_ds_tmp.html ? ae_ds_tmp.html : ''}</textarea>
<!-- Handle SQL type -->
{:else if ae_ds_tmp.type == 'sql'}
<textarea
name="ds_value"
class="textarea type_sql font-mono text-sm"
cols="75"
rows="25"
placeholder="Enter the SQL here"
>{ae_ds_tmp.type == 'sql' && ae_ds_tmp.text ? ae_ds_tmp.text : ''}</textarea>
<!-- Handle text type -->
{:else if ae_ds_tmp.type == 'text'}
<textarea
name="ds_value"
class="textarea type_text"
cols="70"
rows="10"
placeholder="Enter the text here"
>{ae_ds_tmp.type == 'text' ? ae_ds_tmp.text : ''}</textarea>
{/if}
<div class="flex gap-1 justify-center justify-evenly items-center p-1">
<button
type="button"
class="btn variant-soft-warning"
on:click={() => {
if (confirm('Are you sure you want to delete this data store?')) {
trigger = 'delete__ds__code';
// $slct_trigger = 'delete__ds__code';
}
show_edit = false;
show_view = true;
}}
>
<span class="fas fa-trash mx-1"></span>
Delete
</button>
<button
type="button"
class="btn variant-soft-primary"
on:click={() => {
show_edit = false;
show_view = true;
}}
>
<span class="fas fa-times mx-1"></span>
Close
</button>
<button
type="submit"
class="btn variant-soft-primary"
disabled={ds_submit_results instanceof Promise && !ds_submit_results}
on:click={() => {
trigger = 'save__ds__code';
// $slct_trigger = 'save__ds__code';
}}
>
<span class="fas fa-save mx-1"></span>
Save
</button>
{#await ds_submit_results}
<div class="modal-loading">
<span class="fas fa-spinner fa-spin"></span>
<span class="loading-text">
Saving...
</span>
</div>
{:then ds_submit_results}
{#if ds_submit_results}
<div>
<span class="fas fa-check text-green-500"></span>
<span class="saved-text">
Saved
</span>
</div>
{/if}
{/await}
<div
class="ae_debug"
class:hidden={!debug && $ae_loc.debug != 'debug'}
>
submit: {$ae_sess.ds.submit_status}
create: {$ae_sess.ds.create_status}
update: {$ae_sess.ds.update_status}
</div>
</div>
</form>
</section>
{/if}
<!-- {#if mode == 'view'} -->
{#if !ae_ds_tmp.type && !ae_ds_tmp.html && !ae_ds_tmp.json && !ae_ds_tmp.md && !ae_ds_tmp.text}
{#if $ae_loc.manager_access}
<span class="variant-soft-warning">No data found! Is the data store correct or new?</span>
{:else}
<!-- <span class="variant-soft">loading</span> -->
{/if}
{/if}
{#if ae_ds_tmp.type == 'html' && ae_ds_tmp.html}
{@html ae_ds_tmp.html}
{:else if ae_ds_tmp.type == 'html'}
{#if $ae_loc.manager_access}
<span class="variant-soft-warning">No HTML found! Is the data store type correct?</span>
{:else}
<!-- <span class="variant-soft">loading</span> -->
{/if}
{/if}
{#if ae_ds_tmp.type == 'text' && ae_ds_tmp.text}
{ae_ds_tmp.text}
{:else if ae_ds_tmp.type == 'text'}
{#if $ae_loc.manager_access}
<span class="variant-soft-warning">No text found! Is the data store type correct?</span>
{:else}
<!-- <span class="variant-soft">loading</span> -->
{/if}
{/if}
<button
type="button"
class="ae_btn_edit__ds btn hover:variant-glass-warning text-xs absolute top-0 right-0 opacity-30 hover:opacity-100 transition delay-700 hover:delay-200 m-1 p-1"
class:opacity-5={!$ae_loc.manager_access}
class:hidden={!show_edit_btn || !$ae_loc.trusted_access}
on:dblclick={() => {
trigger = 'load__ds__code';
show_edit = true;
show_view = false;
}}
title="Double click to edit data store: {ds_code} with {ae_ds_tmp.account_id ? `account ID=${ae_ds_tmp.account_id}` : 'no account ID'}"
>
<span class="fas fa-edit mx-1"></span>
Edit
</button>
<!-- {/if} -->
{:else}
<!-- Nothing to see yet -->
{/if}
<!-- Text:
<pre>
{val_text}
</pre> -->
<!-- JSON:
<pre>
{val_json}
</pre> -->
{#await ds_get_results}
<div class="modal-loading text-xs absolute bottom-0 left-0 opacity-30 hover:opacity-100 transition delay-700 hover:delay-200">
<span class="fas fa-spinner fa-spin"></span>
<span class="loading-text">
Loading...
</span>
</div>
{/await}
<!-- {ds_loading_status} -->
</div>
<style lang="postcss">
/* .ae_btn_edit__ds {
opacity: .5;
} */
/* The section.edit should be above the rest of the content and centered on the page */
section.edit {
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-width: 80%;
}
.hide {
display: none;
}
</style>

View File

@@ -0,0 +1,862 @@
<script lang="ts">
import { browser } from '$app/environment';
import { liveQuery } from "dexie"; // Use this in the future???
import { Modal } from 'flowbite-svelte';
import { api } from '$lib/api';
import { ae_loc, ae_sess, ae_api, slct, slct_trigger, ae_trig } from '$lib/ae_stores';
import { ae_util } from '$lib/ae_utils/ae_utils';
import type { key_val } from '$lib/ae_stores';
export let log_lvl: number = 1;
export let expire_minutes: number = 10;
export let mount_reload_sec: number = 0;
export let ds_code: string;
export let ds_name: null|string = null;
export let ds_type: string = 'text';
export let for_type: null|string = null;
export let for_id: null|string = null;
console.log(`ae_e_data_store ${ds_code} account_id=${$ae_loc.account_id} for_type=${for_type} for_id=${for_id}`);
// export let store: string = 'local';
// export let display: string = 'block'; // Avoid; Use class list instead
export let class_li: string = ''; // : string[] = [];
export let try_cache: boolean = true;
export let hide: boolean = false; // Hide the entire element
export let show_edit: boolean = false;
export let show_edit_btn: boolean = false;
export let show_view: boolean = true;
// export let show_delete_btn: boolean = false;
export let ds_loaded: boolean = false;
export let debug: boolean = false;
let ae_promises: key_val = {};
// let ae_tmp: key_val = {};
// let ae_triggers: key_val = {};
let ds_get_results: Promise<any>|key_val;
export let ds_loading_status: string = 'starting';
let ds_submit_results: Promise<any>|key_val;
let val_json: key_val;
let val_html: key_val;
let val_md: key_val;
export let val_sql: null|key_val = null;
let val_text: string;
let ds_code_obj =
{
id: null,
account_id: null,
code: ds_code,
name: ds_name,
type: ds_type,
for_type: null, // for_type
for_id: null, // for_id
access_read: null, // 'super', 'manager', 'administrator', 'trusted', 'authenticated', 'anonymous'
access_write: null, // 'super', 'manager', 'administrator', 'trusted', 'authenticated', 'anonymous'
access_delete: null, // 'super', 'manager', 'administrator', 'trusted', 'authenticated', 'anonymous'
html: null,
json: null,
md: null,
text: null,
updated_on: null,
chk_account_id: null,
};
let ae_ds_tmp: key_val;
if (browser && try_cache && localStorage.getItem(`ae_ds__${ds_code}`)) {
if (log_lvl) {
console.log(`ae_e_data_store: Found cached data for ${ds_code}`);
}
ae_ds_tmp = JSON.parse(localStorage.getItem(`ae_ds__${ds_code}`) ?? '{}');
if (log_lvl) {
console.log(`ae_e_data_store cached: ${ds_code} account_id=${$ae_loc.account_id}`, ae_ds_tmp);
}
} else {
ae_ds_tmp = ds_code_obj;
ds_loading_status = 'loading';
}
$ae_sess.ds.submit_status = null;
$ae_sess.ds.create_status = null;
$ae_sess.ds.update_status = null;
let trigger: null|string = null;
// This is a quick check to make sure the data store is not stale. If it is, then we need to trigger a reload.
if (browser && ae_ds_tmp && ae_ds_tmp.loaded_on && ae_ds_tmp.chk_account_id == $ae_loc.account_id) {
console.log(`ae_e_data_store ${ds_code} loaded_on: ${ae_ds_tmp.loaded_on}`);
let loaded_on = new Date(ae_ds_tmp.loaded_on);
let now = new Date();
let diff = now.getTime() - loaded_on.getTime();
let diff_minutes = diff / (1000 * 60);
if (diff_minutes > expire_minutes) {
console.log(`ae_e_data_store: Data Store ${ds_code} stale. Last loaded on: ${loaded_on.toISOString()}`);
// Wait for random number of milliseconds to avoid all data stores being reloaded at the same time.
let random_ms = Math.floor(Math.random() * 500);
console.log(`ae_e_data_store: Random number of milliseconds: ${random_ms}`);
setTimeout(() => {
trigger = 'load__ds__code';
}, random_ms);
}
} else if (browser) {
console.log('ae_e_data_store: No loaded_on date found and or the account_id check failed. Need to trigger reload.');
trigger = 'load__ds__code';
}
// This is a secondary check... The account_id should either be null or match the current account_id.
if (!ae_ds_tmp || !ae_ds_tmp.account_id === null || $ae_loc.account_id == $ae_loc.account_id) {
trigger = 'load__ds__code';
}
if (browser && mount_reload_sec) {
// Wait for random number of milliseconds to avoid all data stores being reloaded at the same time.
let random_ms = Math.floor(Math.random() * mount_reload_sec * 1000);
if (log_lvl) {
console.log(`ae_e_data_store: Random number of milliseconds: ${random_ms}`);
}
setTimeout(() => {
trigger = 'load__ds__code';
}, random_ms);
}
// let ds_code_li = {}; //: key_val; // = ae_loc_tmp.ds;
// console.log(`ae_ ds_code_li = `, ds_code_li);
$: if (trigger == 'load__ds__code' && ds_code && ds_type) {
console.log(`ae_e_data_store: ae_ load__ds__code: ${ds_code} ds_type=${ds_type} for_type=${for_type} for_id=${for_id} ${try_cache}`);
trigger = null;
load_data_store({
code: ds_code,
type: ds_type,
for_type: for_type,
for_id: for_id,
try_cache: try_cache
});
}
async function load_data_store(
{
code,
type = 'text',
for_type = null,
for_id = null,
try_cache = true,
log_lvl = 0
}: {
code: string,
type?: string,
for_type?: string|null,
for_id?: string|null,
try_cache?: boolean,
log_lvl?: number
}
) {
// let ds_code_val = await api.get_data_store_obj_w_code({
ds_get_results = api.get_data_store_obj_w_code({
api_cfg: $ae_api,
data_store_code: code,
data_type: type,
log_lvl: log_lvl
})
.then( function (ds_results) {
// console.log(`ae_ Data Store ${code} = `, ds_results);
if (ds_results) {
if (log_lvl) {
console.log(`ae_e_data_store: Got a result for code ${code}`);
}
if (!ds_results.data_store_id_random) {
console.log('Something went wrong? No data store ID found.');
return false;
}
ds_loaded = true;
ds_loading_status = 'loaded';
// Set the loaded_on datetime to the current time for reference later. This will be used to determine if the data store is stale.
ae_ds_tmp.loaded_on = new Date().toISOString();
// Set the chk_account_id as a backup check to make sure the data store belongs to the account for the current site. This should not be needed, but here we are...
ae_ds_tmp.chk_account_id = $ae_loc.account_id;
ae_ds_tmp.id = ds_results.data_store_id_random;
ae_ds_tmp.account_id = ds_results.account_id_random;
ae_ds_tmp.code = ds_results.code; // This will overwrite whatever was passed in.
ae_ds_tmp.name = ds_results.name;
ae_ds_tmp.type = ds_results.type; // This will overwrite whatever was passed in.
if (type == 'html') {
ae_ds_tmp.html = ds_results.text;
val_html = ds_results.text;
return ds_results.html;
} else if (type == 'json') {
ae_ds_tmp.json = ds_results.json;
val_json = ds_results.json;
return ds_results.json;
} else if (type == 'md') {
ae_ds_tmp.text = ds_results.text;
val_md = ds_results.text;
return ds_results.text;
} else if (type == 'sql') {
ae_ds_tmp.text = ds_results.text;
val_sql = ds_results.text;
return ds_results.text;
} else {
ae_ds_tmp.text = ds_results.text;
val_text = ds_results.text;
return ds_results.text;
}
} else {
ds_loaded = false;
ds_loading_status = 'not found';
}
})
.then(function () {
if (browser && try_cache) {
if (log_lvl) {
console.log(`ae_e_data_store: Caching data store ${code} in localStorage.`);
}
localStorage.setItem(`ae_ds__${code}`, JSON.stringify(ae_ds_tmp));
} else {
// console.log(`ae_e_data_store: Not in browser. Not caching.`);
}
})
.catch(function (error) {
console.log(`Something went wrong. for code ${code}`);
console.log(error);
ds_loading_status = 'error';
return false;
});
// .finally(function (ds_val_result) {
// console.log(`ae_ ds_code_val = `, ds_val_result);
// ae_ds_loc.set(ds_val_result);
// localStorage.setItem(ds_code, ds_val_result);
// sessionStorage.setItem(ds_code, ds_val_result);
// return ds_val_result;
// });
// console.log(`ae_ ds_code_val = `, ds_code_val);
}
async function handle_submit_form(event: any) {
// console.log('*** handle_submit_form() ***');
$ae_sess.ds.submit_status = 'processing';
// Data in
let form_data = new FormData(event.target);
// console.log(form_data);
let data_store_di: key_val = ae_util.extract_prefixed_form_data({prefix: null, form_data: form_data, trim_values: true, bool_tf_str: true, log_lvl: 0});
// console.log(data_store_di);
// Data out
let data_store_do: key_val = {};
if (typeof data_store_di.ds_id_random !== 'undefined') {
data_store_do['data_store_id_random'] = data_store_di.ds_id_random;
}
// if (!$slct.data_store_id) {
if (!ae_ds_tmp.id) {
data_store_do['account_id_random'] = $ae_loc.account_id;
}
if (typeof data_store_di.ds_account_id !== 'undefined' && data_store_di.ds_account_id && data_store_di.ds_use_account_id) {
data_store_do['account_id_random'] = data_store_di.ds_account_id;
} else if (data_store_di.ds_use_account_id && $ae_loc.account_id) {
data_store_do['account_id_random'] = $ae_loc.account_id;
} else {
data_store_do['account_id_random'] = null;
}
if (typeof data_store_di.ds_code !== 'undefined') {
data_store_do['code'] = data_store_di.ds_code;
} else {
data_store_do['code'] = ds_code;
}
if (typeof data_store_di.ds_name !== 'undefined') {
data_store_do['name'] = data_store_di.ds_name;
} else {
data_store_do['name'] = ds_name;
}
if (typeof data_store_di.ds_type !== 'undefined') {
data_store_do['type'] = data_store_di.ds_type;
} else {
data_store_do['type'] = ds_type;
}
if (typeof data_store_di.ds_for_type !== 'undefined' && data_store_di.ds_for_type) {
data_store_do['for_type'] = data_store_di.ds_for_type;
} else {
data_store_do['for_type'] = null;
}
if (typeof data_store_di.ds_for_id !== 'undefined' && data_store_di.ds_for_id) {
data_store_do['for_id_random'] = data_store_di.ds_for_id;
} else {
data_store_do['for_id_random'] = null;
}
if (typeof data_store_di.ds_access_read !== 'undefined') {
data_store_do['access_read'] = data_store_di.ds_access_read;
}
if (typeof data_store_di.ds_access_write !== 'undefined') {
data_store_do['access_write'] = data_store_di.ds_access_write;
}
if (typeof data_store_di.ds_access_delete !== 'undefined') {
data_store_do['access_delete'] = data_store_di.ds_access_delete;
}
if (typeof data_store_di.ds_value !== 'undefined') {
if (data_store_di.ds_type == 'html') {
data_store_do['text'] = data_store_di.ds_value;
} else if (data_store_di.ds_type == 'json') {
data_store_do['json'] = data_store_di.ds_value;
} else if (data_store_di.ds_type == 'md') {
data_store_do['text'] = data_store_di.ds_value;
} else if (data_store_di.ds_type == 'sql') {
data_store_do['text'] = data_store_di.ds_value;
} else {
data_store_do['text'] = data_store_di.ds_value;
}
}
if (typeof data_store_di.ds_enable !== 'undefined') {
data_store_do['enable'] = data_store_di.ds_enable;
} else {
data_store_do['enable'] = true;
}
console.log(data_store_do);
if (!ae_ds_tmp.id) {
// Create
console.log(`ae_ Data Store Create:`, data_store_do);
ds_submit_results = handle_create__data_store({
obj_type: 'data_store',
data: data_store_do
})
.then( function (ds_results) {
console.log(`ae_ Data Store Create Results:`, ds_results);
if (ds_results) {
ae_ds_tmp.id = ds_results.data_store_id_random;
ae_ds_tmp.updated_on = ds_results.updated_on;
}
return ds_results;
})
.finally(function (ds_val_result) {
console.log(`ae_ ds_val_result = `, ds_val_result);
trigger = 'load__ds__code';
$ae_sess.ds.submit_status = 'created';
});
} else {
// Update
console.log(`ae_ Data Store Update:`, data_store_do);
ds_submit_results = handle_update__data_store({
obj_type: 'data_store',
obj_id: ae_ds_tmp.id,
data: data_store_do
})
.then( function (ds_results) {
console.log(`ae_ Data Store Update Results:`, ds_results);
if (ds_results) {
ae_ds_tmp.updated_on = ds_results.updated_on;
}
return ds_results;
// })
// .finally(function (ds_val_result) {
// // console.log(`ae_ ds_code_val = `, ds_val_result);
})
.finally(function () {
// console.log(`ae_ ds_val_result = `, ds_val_result);
console.log(`ae_ load__ds__code: ${ds_code} ${ds_type} ${for_type} ${for_id} ${try_cache}`);
trigger = 'load__ds__code';
$ae_sess.ds.submit_status = 'updated';
});
}
}
async function handle_create__data_store(
{
obj_type,
data
} : {
obj_type: string,
data: key_val
}
) {
console.log('*** handle_create__data_store() ***');
$ae_sess.ds.create_status = 'starting';
ae_promises.api_create__data_store_obj = api.create_ae_obj_crud({
api_cfg: $ae_api,
obj_type: obj_type,
fields: data,
key: $ae_api.api_crud_super_key,
log_lvl: log_lvl
})
.then(async function (create__obj_result) {
if (!create__obj_result) {
console.log('The result was null or false.');
return false;
}
return create__obj_result;
})
.catch(function (error) {
console.log('Something went wrong.');
console.log(error);
return false;
})
.finally(function (create__obj_result) {
$ae_sess.ds.create_status = 'finished';
return create__obj_result;
});
return ae_promises.api_create__data_store_obj;
}
async function handle_update__data_store(
{
obj_type,
obj_id,
data
} : {
obj_type: string,
obj_id: string,
data: key_val
}
) {
console.log('*** handle_update__data_store() ***');
$ae_sess.ds.update_status = 'starting';
ae_promises.update__data_store_obj = api.update_ae_obj_id_crud({
api_cfg: $ae_api,
obj_type: obj_type,
obj_id: obj_id,
fields: data,
key: $ae_api.api_crud_super_key,
log_lvl: log_lvl
})
.then(async function (update__obj_result) {
if (!update__obj_result) {
console.log('The result was null or false.');
return false;
}
return update__obj_result;
})
.catch(function (error) {
console.log('Something went wrong.');
console.log(error);
return false;
})
.finally(function (update__obj_result) {
$ae_sess.ds.update_status = 'finished';
return update__obj_result;
})
return ae_promises.update__data_store_obj;
}
</script>
<div
class="ae__elem__data_store relative {class_li}"
class:hidden={hide}
>
{#if ae_ds_tmp}
{#if debug || $ae_loc.debug == 'debug'}
<pre>
id: {ae_ds_tmp.id},
code: {ae_ds_tmp.code},
type: {ae_ds_tmp.type},
for_type: {ae_ds_tmp.for_type},
for_id: {ae_ds_tmp.for_id},
access_read: {ae_ds_tmp.access_read},
access_write: {ae_ds_tmp.access_write},
access_delete: {ae_ds_tmp.access_delete},
name: {ae_ds_tmp.name},
html: {ae_ds_tmp.html},
json: {ae_ds_tmp.json},
md: {ae_ds_tmp.md},
text: {ae_ds_tmp.text},
updated_on: {ae_ds_tmp.updated_on},
</pre>
{/if}
<!-- {#if show_edit} -->
<!-- <section class="edit z-50"> -->
<!-- Main modal -->
<Modal
title="{ae_ds_tmp.name} - {ae_ds_tmp.code}"
bind:open={show_edit}
autoclose={false}
size="xl"
class="bg-white dark:bg-gray-800 text-gray-800 dark:text-gray-200 rounded-lg border-gray-200 dark:border-gray-700 divide-gray-200 dark:divide-gray-700 shadow-md relative flex flex-col mx-auto w-full divide-y"
>
<form
class="flex flex-col gap-1"
on:submit|preventDefault={handle_submit_form}
>
<input
type="hidden"
name="ds_id_random"
value={ae_ds_tmp.id}
/>
<div class="flex flex-row gap-1">
{#if $ae_loc.trusted_access}
<label for="ds_use_account_id" class="label text-xs inline">Use Account ID
<input
type="checkbox"
name="ds_use_account_id"
class="checkbox"
value="true"
checked={ae_ds_tmp.account_id ? true : false}
/>
</label>
{/if}
{#if $ae_loc.manager_access}
<input
type="text"
name="ds_account_id"
class="input max-w-48 text-xs"
placeholder="Account ID"
value={ae_ds_tmp.account_id}
/>
<input
type="text"
name="ds_code"
class="input text-xs"
placeholder="Data store code"
value={ae_ds_tmp.code}
required
/>
{/if}
</div>
<div class="flex flex-row gap-1">
{#if $ae_loc.trusted_access}
<input
type="text"
name="ds_name"
class="input text-xs"
placeholder="Data store name"
value={ae_ds_tmp.name}
required
/>
{/if}
</div>
<div class="flex flex-row gap-1">
{#if $ae_loc.manager_access}
<input
type="text"
name="ds_type"
class="input max-w-48 text-xs"
placeholder="Data store type (html, json, md, sql, text)"
value={ae_ds_tmp.type}
required
/>
<input
type="text"
name="ds_for_type"
class="input max-w-48 text-xs"
placeholder="Data store For Type"
value={ae_ds_tmp.for_type}
/>
<input
type="text"
name="ds_for_id"
class="input max-w-48 text-xs"
placeholder="Data store For ID"
value={ae_ds_tmp.for_id}
/>
<input
type="text"
name="ds_access_read"
class="input max-w-48 text-xs"
placeholder="Access read"
value={ae_ds_tmp.access_read}
/>
<input
type="text"
name="ds_access_write"
class="input max-w-48 text-xs"
placeholder="Access write"
value={ae_ds_tmp.access_write}
/>
<input
type="text"
name="ds_access_delete"
class="input max-w-48 text-xs"
placeholder="Access delete"
value={ae_ds_tmp.access_delete}
/>
{:else}
Code: {ae_ds_tmp.code}
<!-- Name: {ae_ds_tmp.name} -->
Type: {ae_ds_tmp.type}
{/if}
</div>
<div class="">
<!-- Handle HTML type -->
{#if ae_ds_tmp.type == 'html' || ae_ds_tmp.type == null}
<textarea
name="ds_value"
class="textarea type_html font-mono text-sm"
cols="75"
rows="25"
placeholder="Enter the HTML here"
>{ae_ds_tmp.type == 'html' && ae_ds_tmp.html ? ae_ds_tmp.html : ''}</textarea>
<!-- Handle SQL type -->
{:else if ae_ds_tmp.type == 'sql'}
<textarea
name="ds_value"
class="textarea type_sql font-mono text-sm"
cols="75"
rows="25"
placeholder="Enter the SQL here"
>{ae_ds_tmp.type == 'sql' && ae_ds_tmp.text ? ae_ds_tmp.text : ''}</textarea>
<!-- Handle text type -->
{:else if ae_ds_tmp.type == 'text'}
<textarea
name="ds_value"
class="textarea type_text"
cols="70"
rows="10"
placeholder="Enter the text here"
>{ae_ds_tmp.type == 'text' ? ae_ds_tmp.text : ''}</textarea>
{/if}
</div>
<div class="flex flex-row gap-1 justify-center justify-evenly items-center">
<button
type="button"
class="btn variant-soft-warning"
on:click={() => {
if (confirm('Are you sure you want to delete this data store?')) {
trigger = 'delete__ds__code';
// $slct_trigger = 'delete__ds__code';
}
show_edit = false;
show_view = true;
}}
>
<span class="fas fa-trash mx-1"></span>
Delete
</button>
<!-- <button
type="button"
class="btn variant-soft-primary"
on:click={() => {
show_edit = false;
show_view = true;
}}
>
<span class="fas fa-times mx-1"></span>
Close
</button> -->
<button
type="submit"
class="btn variant-ghost-primary"
disabled={ds_submit_results instanceof Promise && !ds_submit_results}
on:click={() => {
trigger = 'save__ds__code';
// $slct_trigger = 'save__ds__code';
}}
>
<span class="fas fa-save mx-1"></span>
Save
</button>
{#await ds_submit_results}
<div class="modal-loading">
<span class="fas fa-spinner fa-spin"></span>
<span class="loading-text">
Saving...
</span>
</div>
{:then ds_submit_results}
{#if ds_submit_results}
<div>
<span class="fas fa-check text-green-500"></span>
<span class="saved-text">
Saved
</span>
</div>
{/if}
{/await}
<div
class="ae_debug"
class:hidden={!debug && $ae_loc.debug != 'debug'}
>
submit: {$ae_sess.ds.submit_status}
create: {$ae_sess.ds.create_status}
update: {$ae_sess.ds.update_status}
</div>
</div>
</form>
<svelte:fragment slot="footer">
<div class="text-center w-full">
<button
type="button"
on:click={() => {
console.log('Close modal edit data store.');
show_edit = false;
show_view = true;
}}
class="btn btn-sm variant-soft-warning hover:variant-ghost-warning"
>
<span class="fas fa-times mx-1"></span>
Close
</button>
</div>
</svelte:fragment>
</Modal>
<!-- </section> -->
<!-- {/if} -->
<!-- {#if mode == 'view'} -->
{#if !ae_ds_tmp.type && !ae_ds_tmp.html && !ae_ds_tmp.json && !ae_ds_tmp.md && !ae_ds_tmp.text}
{#if $ae_loc.manager_access}
<span class="variant-soft-warning">No data found! Is the data store correct or new?</span>
{:else}
<!-- <span class="variant-soft">loading</span> -->
{/if}
{/if}
{#if ae_ds_tmp.type == 'html' && ae_ds_tmp.html}
{@html ae_ds_tmp.html}
{:else if ae_ds_tmp.type == 'html'}
{#if $ae_loc.manager_access}
<span class="variant-soft-warning">No HTML found! Is the data store type correct?</span>
{:else}
<!-- <span class="variant-soft">loading</span> -->
{/if}
{/if}
{#if ae_ds_tmp.type == 'text' && ae_ds_tmp.text}
{ae_ds_tmp.text}
{:else if ae_ds_tmp.type == 'text'}
{#if $ae_loc.manager_access}
<span class="variant-soft-warning">No text found! Is the data store type correct?</span>
{:else}
<!-- <span class="variant-soft">loading</span> -->
{/if}
{/if}
<button
type="button"
class="ae_btn_edit__ds btn hover:variant-glass-warning text-xs absolute top-0 right-0 opacity-30 hover:opacity-100 transition delay-700 hover:delay-200 m-1 p-1"
class:opacity-5={!$ae_loc.manager_access}
class:hidden={!(
($ae_loc.manager_access && $ae_loc.edit_mode)
||
(show_edit_btn && $ae_loc.administrator_access && $ae_loc.edit_mode)
)}
on:dblclick={() => {
trigger = 'load__ds__code';
show_edit = true;
show_view = false;
}}
title="Double click to edit data store: {ds_code} with {ae_ds_tmp.account_id ? `account ID=${ae_ds_tmp.account_id}` : 'no account ID'}"
>
<span class="fas fa-edit mx-1"></span>
Edit
</button>
<!-- {/if} -->
{:else}
<!-- Nothing to see yet -->
{/if}
<!-- Text:
<pre>
{val_text}
</pre> -->
<!-- JSON:
<pre>
{val_json}
</pre> -->
{#await ds_get_results}
<div class="modal-loading text-xs absolute bottom-0 left-0 opacity-30 hover:opacity-100 transition delay-700 hover:delay-200">
<span class="fas fa-spinner fa-spin"></span>
<span class="loading-text">
Loading...
</span>
</div>
{/await}
<!-- {ds_loading_status} -->
</div>
<style lang="postcss">
/* .ae_btn_edit__ds {
opacity: .5;
} */
/* The section.edit should be above the rest of the content and centered on the page */
/*
section.edit {
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-width: 80%;
}
*/
/* .hide {
display: none;
} */
</style>

View File

@@ -0,0 +1,413 @@
<script lang="ts">
import { createEventDispatcher, onMount, tick } from 'svelte';
import type { key_val } from '$lib/ae_stores';
import { ae_util } from '$lib/ae_utils/ae_utils';
// import { api } from '$lib/api';
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 input_name = 'file_list';
export let container_class_li: string[] = [];
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 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 untrusted_extension_list = ['bin', 'dmg', 'exe', 'js', 'msi', 'php', 'py', 'sh'];
export let legacy_extension_list = ['avi', 'doc', 'ppt', 'xls', 'wmv'];
export let use_selected_file_table = true;
export let file_list_status: null|string = null;
export let processed_file_list: any[] = [];
const dispatch = createEventDispatcher();
export let input_file_list: any = null;
let input_file_list_processed: any[] = [];
onMount(() => {
console.log('** Element Mounted: ** Element Input File');
});
$: if (input_file_list) {
console.log(input_file_list);
process_file_list(input_file_list)
.then(function (result) {
// console.log(result);
if (!result || !result.length) {
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
dispatch(
'input_file_list_updated',
{
element_id: element_id,
input_file_list: input_file_list,
input_file_list_processed: result, // Includes file hash
}
);
});
}
async function process_file_list(file_list) {
console.log('*** process_file_list() ***');
file_list_status = 'processing';
processed_file_list = [];
if (!file_list) {
// file_list_processed = null;
file_list_status = 'none';
// await tick();
return processed_file_list;
}
// const forLoop = async _ => {
// console.log('*** Start ***');
// for (let [i, file_item] of file_list.entries()) { // Not sure why this does not work???
for await (const [i, file_item] of Array.prototype.entries.call(file_list)) {
console.log(i, file_item);
// NOTE: The file list is readonly. The filenames can not be changed here.
if (file_item.name.endsWith('.odpmac') || file_item.name.endsWith('.odpwin') || file_item.name.endsWith('.pptmac') || file_item.name.endsWith('.pptwin') || file_item.name.endsWith('.pptxmac') || file_item.name.endsWith('.pptxwin')) {
console.log('This file extension may need to be fixed? API upload will take care of it.');
// file_item.name = file_item.name.replace('.odpwin', '.odp');
}
let file_data: key_val = {};
let filename = file_item.name;
// console.log(filename);
file_data['filename'] = filename;
let guessed_extension = ae_util.guess_file_extension(filename);
file_data['guessed_extension'] = guessed_extension;
file_data['type'] = file_item.type;
let modified_date = new Date(file_item.lastModified);
file_data['modified_date'] = modified_date;
let modified_datetime_string = ae_util.iso_datetime_formatter(modified_date, 'datetime_medium');
file_data['modified_datetime_string'] = modified_datetime_string;
let file_size_bytes = file_item.size;
file_data['file_size_bytes'] = file_size_bytes;
let file_size_string = ae_util.format_bytes(file_item.size, 2);
file_data['file_size_string'] = file_size_string;
// // NOTE: Calculate the hash of the file before upload. Check if this exact file has already been uploaded.
// let file_reader = new FileReader();
// file_reader.onload = async function() {
// const hash_buffer = crypto.subtle.digest('SHA-256', file_reader.result);
// let hash_hex_test = hash_buffer.then(async function (result_buffer) {
// const hash_array = Array.from(new Uint8Array(result_buffer)); // convert buffer to byte array
// const hash_hex = hash_array.map(b => b.toString(16).padStart(2, '0')).join('');
// console.log(`File hash hex? ${hash_hex}`);
// file_data['hash_sha256'] = hash_hex;
// return hash_hex;
// })
// .catch(function (error) {
// console.log('Something went wrong?', error);
// });
// return hash_hex_test;
// // file_data['hash_hex_test'] = hash_hex_test;
// // const hash_buffer = await crypto.subtle.digest('SHA-256', file_reader.result);
// // let hash_str = await new TextDecoder().decode(hash_buffer);
// // console.log(`File hash string? ${hash_str}`);
// // file_data['hash_str'] = hash_str;
// // const hash_array = Array.from(new Uint8Array(hash_buffer)); // convert buffer to byte array
// // const hash_hex = hash_array.map(b => b.toString(16).padStart(2, '0')).join('');
// // console.log(`File hash hex? ${hash_hex}`);
// // file_data['hash_sha256'] = hash_hex;
// // return hash_hex_test;
// // return hash_hex;
// }
// // file_reader.then(function (result) {
// // console.log(`File hash hex? ${result}`);
// // return hash_hex;
// // })
// // .catch(function (error) {
// // console.log('No results returned or failed.', error);
// // });
// // file_data['hash_sha256'] = file_reader.readAsArrayBuffer(file_item);
let warning_untrusted_extension = false;
let warning_legacy_extension = false;
let warning_size = false;
let warning_message = null;
if (untrusted_extension_list.includes(guessed_extension)) {
console.log('This is an untrusted extension. Going to warn.')
warning_untrusted_extension = true;
warning_message = 'It appears this an untrusted file type and is likely meant to be an executable or installable application. It is <strong>strongly</strong> recommended that this file not be used.';
} else if (legacy_extension_list.includes(guessed_extension)) {
console.log('This is a legacy extension. Going to warn.')
warning_legacy_extension = true;
if (guessed_extension == 'ppt') {
warning_message = 'It appears this is a legacy PowerPoint file and has not been officially supported since Office PowerPoint 2003. This file is known to have issues and may not work well. It is <strong>strongly</strong> recommended that this file be saved using the modern PPTX format.';
} else if (guessed_extension == 'avi') {
warning_message = 'It appears this is a video file using the AVI format. It is <strong>strongly</strong> recommended that this file be re-saved as an MP4, MOV, MKV, or MPG/MPEG. The file will also likely be much smaller.';
} else if (guessed_extension == 'wmv') {
warning_message = 'It appears this is a video file using Microsoft\'s WMV format. It is <strong>strongly</strong> recommended that this file be re-saved as an MP4, MOV, MKV, or MPG/MPEG.';
} else {
warning_message = 'It appears this is a legacy or not very well supported file format. It is <strong>strongly</strong> recommended that it be saved in an alternative format if possible.';
}
} else if (file_size_bytes > 52428800) {
// 50 MB = 52428800 bytes
// 100 MB = 104857600 bytes
console.log(`This is a large file size ${file_size_bytes / 1048576} MB (${file_size_bytes} bytes). Going to warn.`);
warning_size = true;
if (file_size_bytes > 2147483648) { // > 2 GB
warning_message = `This file size (${file_size_string}) is very large and will take at <strong>least</strong> a few minutes to upload depending on your network connection. In some cases it may be worth compressing the file or embedded media. Most audio, image, and video files can be compressed without a significant loss in quality. Be sure you have a stable network connection, especially if you are uploading over a wireless connection. Many business (convention centers, hotels, restaurants, etc) cap upload speeds significantly.`;
} else if (file_size_bytes > 209715200) { // > 200 MB
warning_message = `This file size (${file_size_string}) is large and will likely take at <strong>least</strong> a few minutes to upload depending on your network connection. Be sure you have a stable network connection, especially if you are uploading over a wireless connection. Many business (convention centers, hotels, restaurants, etc) cap upload speeds significantly. In some cases it may be worth compressing the file or embedded media. Many audio, image, and video files can be compressed without a significant loss in quality.`;
} else if (file_size_bytes > 104857600) { // 100 MB to 200 MB
warning_message = `This file size (${file_size_string}) is large and will likely take a few minutes to upload depending on your network connection. Be sure you have a stable network connection. In some cases it may be worth compressing the file or embedded media. Many audio, image, and video files can be compressed without a significant loss in quality.`;
} else { // 50 to 100 MB
warning_message = `This file size (${file_size_string}) is large and may take a few minutes to upload depending on your network connection. In some cases it may be worth compressing the file or embedded media. Many audio, image, and video files can be compressed without a significant loss in quality.`;
}
} else {
}
file_data['warning_untrusted_extension'] = warning_untrusted_extension;
file_data['warning_legacy_extension'] = warning_legacy_extension;
file_data['warning_size'] = warning_size;
file_data['warning_message'] = warning_message;
file_data['uploaded'] = null;
file_data['uploaded_bytes'] = null;
// input_file_list_processed.push(JSON.parse(JSON.stringify(file_data)));
// input_file_list_processed = input_file_list_processed;
// console.log(get_file_hash(file_item));
// console.log(await get_file_hash(file_item));
let file_hash = null;
// Only hash files less than 2 GB (2147483648 bytes)!!!
console.log(`File size: ${file_size_bytes / 1048576} MB (${file_size_bytes} bytes)`);
if (file_size_bytes < 2000000000) { // > 2 GB 2 147 483 648
file_hash = await ae_util.get_file_hash(file_item);
} else {
// File size in MB
console.log(`File is too large to hash. File size: ${file_size_bytes / 1048576} MB`);
}
if (file_hash) {
console.log(`Found file hash to lookup: ${ae_util.shorten_string({string: file_hash})}`);
file_data['hash_sha256'] = file_hash;
let check_hosted_file_obj_w_hash_result = await core_func.check_hosted_file_obj_w_hash({
api_cfg: $ae_api,
hosted_file_hash: file_hash
});
// console.log(check_hosted_file_obj_w_hash_result);
if (check_hosted_file_obj_w_hash_result && check_hosted_file_obj_w_hash_result.hosted_file_found_check) {
console.log('Matching hash!!!');
file_data['hash_sha256_match'] = true;
// $ae_events.pres_mgmt.new_upload_list[i].hash_sha256_match = true;
// $ae_events = $ae_events;
}
} else {
file_data['hash_sha256'] = null;
file_data['hash_sha256_match'] = false;
}
processed_file_list.push(file_data);
// input_file_list_processed.push(file_data);
}
file_list_status = 'ready';
console.log(processed_file_list);
// return JSON.parse(JSON.stringify(processed_file_list));
return processed_file_list
}
function remove_file_from_filelist(index) {
console.log('*** remove_file_from_filelist() ***');
// Can not use something like this because it is readonly:
const dt = new DataTransfer();
// let input = document.getElementById(input_element_id);
let input_element = document.querySelector('input[type="file"].svelte_input_file_element');
if (!input_element) {
console.error('Could not find the input element.');
return false;
}
let files = input_file_list;
if (!files || !files.length) {
console.error('No files found in the file list.');
file_list_status = null;
return false;
}
for (let i = 0; i < files.length; i++) {
const file = files[i];
if (index !== i) // Only include the file if it does not match the index value.
dt.items.add(file);
}
// NOTE: I thought just setting the input_element.files OR input_file_list would trigger the input_file_list change.
// input_element.files = Object.assign({}, dt.files);
input_element.files = dt.files; // Assign the updates list
// input_file_list = null;
input_file_list = dt.files; // I feel like this should not need to be done, but doing it anyways.
return true;
}
</script>
<div class="svelte_element ae_element ae_input_file flex flex-col gap-1 items-center justify-center {container_class_li.join(' ')} text-center">
<label
for={element_id}
class="svelte_input_file_label text-center"
>
<div>
<span class="fas fa-upload"></span>
<!-- Select files to upload -->
<!-- <span class="fas fa-file-archive"></span> -->
<strong>Upload your files</strong>
<!-- (drag and drop) -->
</div>
<span>
Presentation related files only<br>
(PowerPoint, Keynote, PDF, mp4, Word Doc, Excel, txt, etc)
</span>
</label>
<input
id={element_id}
type="file"
bind:files={input_file_list}
{multiple}
{required}
{accept}
name={input_name}
class="svelte_input_file_element {input_class_li.join(' ')}"
/>
{#if file_list_status == 'processing'}
<div class="file_list_status ae_warning variant-ghost-warning p-1 m-1">
<span class="fas fa-spinner fa-spin m-1"></span> Processing selected file list...
</div>
{/if}
<!-- {#await input_file_list_processed} -->
<!-- {:then} -->
{#if use_selected_file_table && input_file_list_processed && input_file_list_processed.length}
<strong>Files selected for upload</strong>
<table class="slct_file_list text-sm {table_class_li.join(' ')}">
<thead>
<tr>
<th>Remove</th>
<th>Filename</th>
<th>Modified</th>
<th>Size</th>
<!-- <th>Type</th> -->
<th>Ext</th>
<th>Hash</th>
</tr>
</thead>
{#each input_file_list_processed as file_list_item, file_index}
<tbody>
<tr>
<td class="file_remove">
<button
on:click|preventDefault={() => { (remove_file_from_filelist(file_index)); }}
class="btn btn-md variant-soft-warning hover:variant-filled-secondary m-1"
title="Remove file from upload list">
<span class="fas fa-minus"></span>
</button>
</td>
<td class="file_filename">{file_list_item.filename}</td>
<td class="file_last_modified">{file_list_item.modified_datetime_string}</td>
<td
class="file_size"
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} -->
</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
class="file_extension"
class:bg-red-200={file_list_item.warning_untrusted_extension}
class:bg-pink-200={file_list_item.warning_legacy_extension}
>
{file_list_item.guessed_extension}
</td>
<td
class="file_hash file_hash256"
class:bg-pink-200={file_list_item.hash_sha256_match}
>
{ae_util.shorten_string({string: file_list_item.hash_sha256, begin_length: 5, end_length: 4, wildcard_length: 2})}
</td>
</tr>
</tbody>
{/each}
</table>
{/if}
</div>
<style>
th {
text-align: center;
/* font-size: smaller; */
}
td {
text-align: center;
}
.file_last_modified {
font-size: smaller;
}
.file_size, .file_type {
/* font-size: smaller; */
}
.file_hash {
font-family: 'Courier New', Courier, monospace;
}
</style>

View File

@@ -0,0 +1,386 @@
<script lang="ts">
import { createEventDispatcher, onMount, tick } from 'svelte';
import type { key_val } from '$lib/ae_stores';
import { ae_util } from '$lib/ae_utils/ae_utils';
// import { api } from '$lib/api';
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 container_class_li: string[] = [];
export let table_class_li: string[] = ['table', 'table-sm', 'table-striped', 'table-hover' , 'text-sm'];
export let untrusted_extension_list = ['bin', 'dmg', 'exe', 'js', 'msi', 'php', 'py', 'sh'];
export let legacy_extension_list = ['avi', 'doc', 'ppt', 'xls', 'wmv'];
export let use_selected_file_table = true;
export let input_file_list: any = null;
export let file_list_status: null|string = null;
export let processed_file_list: any[] = [];
// const dispatch = createEventDispatcher();
// let input_file_list_processed: any[] = [];
onMount(() => {
console.log('** Element Mounted: ** Element Input File');
});
$: if (input_file_list) {
console.log(input_file_list);
process_file_list(input_file_list)
.then(function (result) {
// 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
// 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';
}
async function process_file_list(file_list) {
console.log('*** process_file_list() ***');
file_list_status = 'processing';
processed_file_list = [];
if (!file_list) {
// file_list_processed = null;
file_list_status = 'none';
// await tick();
return processed_file_list;
}
// const forLoop = async _ => {
// console.log('*** Start ***');
// for (let [i, file_item] of file_list.entries()) { // Not sure why this does not work???
for await (const [i, file_item] of Array.prototype.entries.call(file_list)) {
console.log(i, file_item);
// NOTE: The file list is readonly. The filenames can not be changed here.
if (file_item.name.endsWith('.odpmac') || file_item.name.endsWith('.odpwin') || file_item.name.endsWith('.pptmac') || file_item.name.endsWith('.pptwin') || file_item.name.endsWith('.pptxmac') || file_item.name.endsWith('.pptxwin')) {
console.log('This file extension may need to be fixed? API upload will take care of it.');
// file_item.name = file_item.name.replace('.odpwin', '.odp');
}
let file_data: key_val = {};
let filename = file_item.name;
// console.log(filename);
file_data['filename'] = filename;
let guessed_extension = ae_util.guess_file_extension(filename);
file_data['guessed_extension'] = guessed_extension;
file_data['type'] = file_item.type;
let modified_date = new Date(file_item.lastModified);
file_data['modified_date'] = modified_date;
let modified_datetime_string = ae_util.iso_datetime_formatter(modified_date, 'datetime_medium');
file_data['modified_datetime_string'] = modified_datetime_string;
let file_size_bytes = file_item.size;
file_data['file_size_bytes'] = file_size_bytes;
let file_size_string = ae_util.format_bytes(file_item.size, 2);
file_data['file_size_string'] = file_size_string;
// // NOTE: Calculate the hash of the file before upload. Check if this exact file has already been uploaded.
// let file_reader = new FileReader();
// file_reader.onload = async function() {
// const hash_buffer = crypto.subtle.digest('SHA-256', file_reader.result);
// let hash_hex_test = hash_buffer.then(async function (result_buffer) {
// const hash_array = Array.from(new Uint8Array(result_buffer)); // convert buffer to byte array
// const hash_hex = hash_array.map(b => b.toString(16).padStart(2, '0')).join('');
// console.log(`File hash hex? ${hash_hex}`);
// file_data['hash_sha256'] = hash_hex;
// return hash_hex;
// })
// .catch(function (error) {
// console.log('Something went wrong?', error);
// });
// return hash_hex_test;
// // file_data['hash_hex_test'] = hash_hex_test;
// // const hash_buffer = await crypto.subtle.digest('SHA-256', file_reader.result);
// // let hash_str = await new TextDecoder().decode(hash_buffer);
// // console.log(`File hash string? ${hash_str}`);
// // file_data['hash_str'] = hash_str;
// // const hash_array = Array.from(new Uint8Array(hash_buffer)); // convert buffer to byte array
// // const hash_hex = hash_array.map(b => b.toString(16).padStart(2, '0')).join('');
// // console.log(`File hash hex? ${hash_hex}`);
// // file_data['hash_sha256'] = hash_hex;
// // return hash_hex_test;
// // return hash_hex;
// }
// // file_reader.then(function (result) {
// // console.log(`File hash hex? ${result}`);
// // return hash_hex;
// // })
// // .catch(function (error) {
// // console.log('No results returned or failed.', error);
// // });
// // file_data['hash_sha256'] = file_reader.readAsArrayBuffer(file_item);
let warning_untrusted_extension = false;
let warning_legacy_extension = false;
let warning_size = false;
let warning_message = null;
if (untrusted_extension_list.includes(guessed_extension)) {
console.log('This is an untrusted extension. Going to warn.')
warning_untrusted_extension = true;
warning_message = 'It appears this an untrusted file type and is likely meant to be an executable or installable application. It is <strong>strongly</strong> recommended that this file not be used.';
} else if (legacy_extension_list.includes(guessed_extension)) {
console.log('This is a legacy extension. Going to warn.')
warning_legacy_extension = true;
if (guessed_extension == 'ppt') {
warning_message = 'It appears this is a legacy PowerPoint file and has not been officially supported since Office PowerPoint 2003. This file is known to have issues and may not work well. It is <strong>strongly</strong> recommended that this file be saved using the modern PPTX format.';
} else if (guessed_extension == 'avi') {
warning_message = 'It appears this is a video file using the AVI format. It is <strong>strongly</strong> recommended that this file be re-saved as an MP4, MOV, MKV, or MPG/MPEG. The file will also likely be much smaller.';
} else if (guessed_extension == 'wmv') {
warning_message = 'It appears this is a video file using Microsoft\'s WMV format. It is <strong>strongly</strong> recommended that this file be re-saved as an MP4, MOV, MKV, or MPG/MPEG.';
} else {
warning_message = 'It appears this is a legacy or not very well supported file format. It is <strong>strongly</strong> recommended that it be saved in an alternative format if possible.';
}
} else if (file_size_bytes > 52428800) {
// 50 MB = 52428800 bytes
// 100 MB = 104857600 bytes
console.log(`This is a large file size ${file_size_bytes / 1048576} MB (${file_size_bytes} bytes). Going to warn.`);
warning_size = true;
if (file_size_bytes > 2147483648) { // > 2 GB
warning_message = `This file size (${file_size_string}) is very large and will take at <strong>least</strong> a few minutes to upload depending on your network connection. In some cases it may be worth compressing the file or embedded media. Most audio, image, and video files can be compressed without a significant loss in quality. Be sure you have a stable network connection, especially if you are uploading over a wireless connection. Many business (convention centers, hotels, restaurants, etc) cap upload speeds significantly.`;
} else if (file_size_bytes > 209715200) { // > 200 MB
warning_message = `This file size (${file_size_string}) is large and will likely take at <strong>least</strong> a few minutes to upload depending on your network connection. Be sure you have a stable network connection, especially if you are uploading over a wireless connection. Many business (convention centers, hotels, restaurants, etc) cap upload speeds significantly. In some cases it may be worth compressing the file or embedded media. Many audio, image, and video files can be compressed without a significant loss in quality.`;
} else if (file_size_bytes > 104857600) { // 100 MB to 200 MB
warning_message = `This file size (${file_size_string}) is large and will likely take a few minutes to upload depending on your network connection. Be sure you have a stable network connection. In some cases it may be worth compressing the file or embedded media. Many audio, image, and video files can be compressed without a significant loss in quality.`;
} else { // 50 to 100 MB
warning_message = `This file size (${file_size_string}) is large and may take a few minutes to upload depending on your network connection. In some cases it may be worth compressing the file or embedded media. Many audio, image, and video files can be compressed without a significant loss in quality.`;
}
} else {
}
file_data['warning_untrusted_extension'] = warning_untrusted_extension;
file_data['warning_legacy_extension'] = warning_legacy_extension;
file_data['warning_size'] = warning_size;
file_data['warning_message'] = warning_message;
file_data['uploaded'] = null;
file_data['uploaded_bytes'] = null;
// input_file_list_processed.push(JSON.parse(JSON.stringify(file_data)));
// input_file_list_processed = input_file_list_processed;
// console.log(get_file_hash(file_item));
// console.log(await get_file_hash(file_item));
let file_hash = null;
// Only hash files less than 2 GB (2147483648 bytes)!!!
console.log(`File size: ${file_size_bytes / 1048576} MB (${file_size_bytes} bytes)`);
if (file_size_bytes < 2000000000) { // > 2 GB 2 147 483 648
file_hash = await ae_util.get_file_hash(file_item);
} else {
// File size in MB
console.log(`File is too large to hash. File size: ${file_size_bytes / 1048576} MB`);
}
if (file_hash) {
console.log(`Found file hash to lookup: ${ae_util.shorten_string({string: file_hash})}`);
file_data['hash_sha256'] = file_hash;
let check_hosted_file_obj_w_hash_result = await core_func.check_hosted_file_obj_w_hash({
api_cfg: $ae_api,
hosted_file_hash: file_hash
});
// console.log(check_hosted_file_obj_w_hash_result);
if (check_hosted_file_obj_w_hash_result && check_hosted_file_obj_w_hash_result.hosted_file_found_check) {
console.log('Matching hash!!!');
file_data['hash_sha256_match'] = true;
// $ae_events.pres_mgmt.new_upload_list[i].hash_sha256_match = true;
// $ae_events = $ae_events;
}
} else {
file_data['hash_sha256'] = null;
file_data['hash_sha256_match'] = false;
}
processed_file_list.push(file_data);
// input_file_list_processed.push(file_data);
}
file_list_status = 'ready';
console.log(processed_file_list);
// return JSON.parse(JSON.stringify(processed_file_list));
return processed_file_list
}
function remove_file_from_filelist(index) {
console.log('*** remove_file_from_filelist() ***');
// Can not use something like this because it is readonly:
const dt = new DataTransfer();
// let input = document.getElementById(input_element_id);
let input_element = document.querySelector('input[type="file"].svelte_input_file_element');
if (!input_element) {
console.error('Could not find the input element.');
return false;
}
let files = input_file_list;
if (!files || !files.length) {
console.error('No files found in the file list.');
file_list_status = null;
return false;
}
for (let i = 0; i < files.length; i++) {
const file = files[i];
if (index !== i) // Only include the file if it does not match the index value.
dt.items.add(file);
}
// NOTE: I thought just setting the input_element.files OR input_file_list would trigger the input_file_list change.
// input_element.files = Object.assign({}, dt.files);
input_element.files = dt.files; // Assign the updates list
// input_file_list = null;
input_file_list = dt.files; // I feel like this should not need to be done, but doing it anyways.
return true;
}
</script>
<div class="svelte_element ae_element ae_input_file flex flex-col gap-1 items-center justify-center {container_class_li.join(' ')} text-center">
{#if file_list_status == 'processing'}
<div class="file_list_status ae_warning variant-ghost-warning p-1 m-1">
<span class="fas fa-spinner fa-spin m-1"></span> Processing selected file list...
</div>
{/if}
<!-- {#await processed_file_list} -->
<!-- {:then} -->
{#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>
<tr>
<th>Remove</th>
<th>Filename</th>
<th>Modified</th>
<th>Size</th>
<!-- <th>Type</th> -->
<th>Ext</th>
<th>Hash</th>
</tr>
</thead>
{#each processed_file_list as file_list_item, file_index}
<tbody>
<tr>
<td class="file_remove">
<button
on:click|preventDefault={() => { (remove_file_from_filelist(file_index)); }}
class="btn btn-md variant-soft-warning hover:variant-filled-secondary m-1"
title="Remove file from upload list">
<span class="fas fa-minus"></span>
</button>
</td>
<td class="file_filename">{file_list_item.filename}</td>
<td class="file_last_modified">{file_list_item.modified_datetime_string}</td>
<td
class="file_size"
class:bg-pink-200={file_list_item.warning_size}
>
{file_list_item.file_size_string}
{#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
class="file_extension"
class:bg-red-200={file_list_item.warning_untrusted_extension}
class:bg-pink-200={file_list_item.warning_legacy_extension}
>
{file_list_item.guessed_extension}
</td>
<td
class="file_hash file_hash256"
class:bg-pink-200={file_list_item.hash_sha256_match}
>
{ae_util.shorten_string({string: file_list_item.hash_sha256, begin_length: 5, end_length: 4, wildcard_length: 2})}
</td>
</tr>
</tbody>
{/each}
</table>
{/if}
</div>
<style>
th {
text-align: center;
/* font-size: smaller; */
}
td {
text-align: center;
}
.file_last_modified {
font-size: smaller;
}
.file_size, .file_type {
/* font-size: smaller; */
}
.file_hash {
font-family: 'Courier New', Courier, monospace;
}
</style>

View File

@@ -0,0 +1,574 @@
<script lang="ts">
import { createEventDispatcher, onMount } from 'svelte';
import util from './utilities.js';
// import Select_element_lu from './element_select_lu.svelte';
/* *** BEGIN *** Core input settings */
export let id_random: string = ''; // OSIT Aether specific
export let obj_type: string = ''; // OSIT Aether specific
export let obj_prop_name: string = ''; // OSIT Aether specific
export let use_name_prefix: boolean = false;
export let name: string = (use_name_prefix ? `${obj_type}__${obj_prop_name}` : obj_prop_name);
// console.log(name);
export let id: string = `${obj_type}__${obj_prop_name}--${id_random}`; // Same as the value for "for"
// console.log(id);
export let value: null|boolean|number|string = null; // The current value of the property
console.log(`Input name=${name} value=${value}`);
export let default_value: null|boolean|number|string = null; // The default value for when value is ''
// console.log('Default Value:', default_value);
export let original_value: null|boolean|number|string = value; // The original value
console.log('Original Value', original_value);
export let data_type: string = typeof value; // boolean, number, string, json
console.log('Data Type:', data_type);
// hidden, text, email, date, number, select, checkbox, radio, textarea, etc
export let type: string = 'text'; // Input type
let set_input_type = (node) => {
node.type = 'text';
};
let input_element_type_list = ['checkbox', 'date', 'email', 'hidden', 'number', 'text'];
if (input_element_type_list.includes(type)) {
set_input_type = (node) => {
node.type = type;
};
} else {
}
console.log(`Input name=${name} value=${value} type=${type}`);
export let disabled: boolean = false; // attribute format: disabled
export let readonly: boolean = false; // attribute format: readonly="readonly"
export let required: boolean = false; // attribute format: required="required"
export let pattern: null|string = null;
export let focus: boolean = false;
/* *** END *** Core input settings */
/* *** BEGIN *** Container content, layout, and behavior */
// Input element specific label and placeholder
export let label: string = '';
export let label_date: string = 'Date';
export let label_time: string = 'Time';
export let placeholder: string = label;
// Input description for container
export let description: string = ''; // Description
// Layout and style
export let content_layout: string = ''; // Default empty is label wrap first, label_start, label_end, floating_input
export let class_li: string[] = []; // Classes for the input element
export let style: string = ''; // Style for the input element
export let display: string = ''; // Default empty is inline. inline, block, inline-block, break (break after)
export let label_class_li: string[] = [];
export let label_style: string = '';
export let label_display: string = ''; // Default empty is inline. inline, block, inline-block, break (break after)
export let label_location: string = 'start'; // start, end
export let description_location: string = 'end'; // start, end
export let container_class_li: string[] = []; // Classes for the container element
export let container_style: string = '';
export let container_display: string = ''; // Default empty is div block. inline, block, inline-block, break (break after)
export let multipart_class_li: string[] = [];
export let input_mode: null|string = null; // This is for special/custom modes like a rich text editor or search.
console.log(`Input input_mode=${input_mode}`);
/* *** END *** Container content, layout, and behavior */
/* *** BEGIN *** Input type specific */
// For checkbox, radio, and select option
export let option_li: any[] = []; // For checkbox, radio, and select inputs. Not specific to select options. List of key value pairs.
export let option_none: boolean = false; // If set to true then it will add an option using the select_option_none_text value
export let option_none_text: string = '-- Not Selected --'; // If set to true then it will add an option using the select_option_none_text value
// For textarea
export let size: number = null;
export let rows: number = 3;
export let cols: number = 80;
if (type == 'textarea') {
console.log(`Input textarea size=${size} rows=${rows} cols=${cols}`);
}
// For custom date_time. Not "date" or "time" input type only.
export let date_time_tz: null|string = null;
let value_datetime = null;
let value_date = null;
let value_time = null;
if (type == 'date_time' && value) {
console.log(`date_time value: ${value}`);
value_datetime = new Date(value+'Z'); // Append the Z so it knows it is UTC (YYY-MM-DDTHH:mm:ssZ)
console.log(value_datetime);
value_datetime = util.iso_datetime_formatter(value_datetime,'datetime_iso');
value_date = util.iso_datetime_formatter(value_datetime,'date_iso');
value_time = util.iso_datetime_formatter(value_datetime,'time_iso');
// value_date = value_datetime.toLocaleDateString();
// value_date = value_datetime.toISOString();
// value_time = value_datetime.toLocaleTimeString();
// value_time = value_datetime.toISOString();
} else if (type == 'date_time') {
console.log('No datetime value passed');
}
if (type == 'date_time') {
console.log(`Input date_time value_datetime=${value_datetime} value_date=${value_date} value_time=${value_time} date_time_tz=${date_time_tz}`);
}
/* *** END *** Input type specific */
/* THIS NEEDS TO BE CLEANED UP */
let multipart_style;
let label_begin;
let checkbox_none;
let checked;
let checkbox_none_text;
let checkbox_li;
let radio_option_class_li;
let radio_none;
let radio_none_text;
let radio_li;
let value_new_line;
let select_option_none;
let select_option_li_lu_name;
let select_option_li;
let select_option_none_text;
/* ^^^ THIS NEEDS TO BE CLEANED UP ^^^ */
const dispatch = createEventDispatcher();
// type Input = {
// name: string;
// value: number;
// };
// let input: Input;
/*
* container_element: span, div, section
* container_class_li: []
* content_layout: inline, break, bs_floating
* content_order: label_value_description, value_label_description, label_description_value
* label_class_li: []
* class_li: []
* start_desc: string
* end_desc: string
*
*/
onMount(() => {
console.log(`** Element Mounted: ** Element Input v2: ${obj_type} ${obj_prop_name}; type=${data_type}; value=${value}`);
if (input_mode == 'editor_basic_200') {
rich_editor();
}
});
// $: if (value) {
// console.log(`input name=${name} value=${value}`);
// console.log(typeof value);
// } else if (typeof value === 'undefined') {
// console.log(`input name=${name} value=undefined; resetting to ''`);
// value = '';
// }
$: if (disabled) { disabled=true; } // else { disabled=false; }
$: if (readonly) { readonly=true; } // else { readonly=false; }
$: if (required) { required=true; } // else { required=true; }
$: if (data_type) {
console.log(`Input value data_type=${data_type}`);
} else if (data_type == 'json') {
console.log(`Need to convert JSON object to string.`);
if (typeof value === 'object') {
value = JSON.stringify(value);
console.log(`Value as data type (${data_type}): ${value}`);
} else {
console.log('Value is not an object type')
console.log(typeof value);
}
}
// // input_mode options: null or '' assume 'text', 'none', 'text', 'tel', 'url', 'email', 'numeric', 'decimal', and 'search'
// $: if (input_mode === null || input_mode == '') {
// input_mode = 'text';
// } else if (input_mode == 'json') {
// } else if (input_mode == 'editor_basic_200') {
// }
// console.log(`input_mode=${input_mode}`);
$: if (container_display == '' || container_display == 'block') {
console.log(`input name=${name} container_display=${container_display}`);
// NOTE: Using a div will be displayed as block by default
} else if (container_display == 'inline') {
console.log(`input name=${name} container_display=${container_display}`);
container_class_li.push('container_inline');
container_style = 'display: inline;'
} else if (container_display == 'inline-block') {
console.log(`input name=${name} container_display=${container_display}`);
container_class_li.push('container_inline_block');
container_style = 'display: inline-block;'
} else if (typeof container_display === 'undefined') {
console.log(`input name=${name} container_display=${container_display}`);
}
$: if (content_layout == '' || content_layout == 'label_begin') {
console.log(`input name=${name} content_layout=${content_layout}`);
// label_begin = true;
} else if (content_layout == 'label_end') {
console.log(`input name=${name} content_layout=${content_layout}`);
// label_begin = false;
} else if (content_layout == 'floating_input') {
console.log(`input name=${name} content_layout=${content_layout}`);
// label_begin = false;
if (type != 'date_time') {
container_class_li.push('form-floating'); // set the container class list
} else {
multipart_class_li.push('form-floating'); // set the container with multi input parts class list
}
if (type === 'select') {
class_li.push('form-select'); // set the select class list
} else {
console.log('Make form-control???');
class_li.push('form-control'); // set the input, select, textarea class list
}
if (type === 'textarea') {
let estimate_row_rem = rows + 5.5;
style = `height: calc(2px + ${estimate_row_rem}rem);`;
}
} else if (typeof content_layout === 'undefined') {
console.log(`input name=${name} content_layout=${content_layout}`);
}
// function handle_oninput_dispatch() {
// console.log(input);
// dispatch('oninput', {
// name: input.name,
// value: input.value,
// });
// }
function handle_oninput_dispatch(event) {
console.log(event.target);
console.log(value);
dispatch('oninput', {
name: event.target.name,
value: event.target.value,
});
}
function rich_editor() {
console.log('*** rich_editor() ***');
// let test_element = $('.editor_basic_200');
// console.log(test_element);
// let textarea_element = document.querySelector('.editor_basic_200');
// let toolbar_element = document.querySelector('.quilljs_toolbar');
// console.log(toolbar_element);
let editor_element = document.querySelector('.quilljs_editor');
console.log(editor_element);
// var editor = new Quill(editor_element, {
// modules: {
// 'multi-cursor': true,
// 'toolbar': { container: '#quilljs_toolbar' },
// // 'link-tooltip': true,
// },
// placeholder: 'Text goes here',
// theme: 'snow'
// });
var editor = new Quill(editor_element, {
modules: {
'multi-cursor': true,
toolbar: [
[{
header: [1, 2, false]
}],
['bold', 'italic', 'underline'],
['image', 'code-block']
]
// 'link-tooltip': true,
},
placeholder: 'Text goes here',
theme: 'snow'
});
/*
textarea_element.summernote(
{
tabsize: 4,
height: 200,
toolbar: [
['cleaner',['cleaner']], // The Button
['edit', ['undo', 'redo']],
['font', ['bold', 'italic', 'underline', 'strikethrough', 'superscript', 'subscript', 'clear']],
['color', ['forecolor']],
['para', ['ul', 'ol', 'paragraph']],
['insert', ['link']],
['view', ['codeview', 'help']]
],
cleaner:{
action: 'both', // both|button|paste 'button' only cleans via toolbar button, 'paste' only clean when pasting content, both does both options.
newline: '<br>', // Summernote's default is to use '<p><br></p>'
notStyle: '', // Position of Notification
icon: '<i class="fas fa-paste"></i>',
keepHtml: true, // Remove all Html formats
keepOnlyTags: ['<p>', '<br>', '<ul>', '<li>', '<b>', '<strong>','<i>', '<a>'], // If keepHtml is true, remove all tags except these
keepClasses: false, // Remove Classes
badTags: ['style', 'script', 'applet', 'embed', 'noframes', 'noscript', 'html'], // Remove full tags with contents
badAttributes: ['style', 'start'], // Remove attributes from remaining tags
limitChars: false, // 0/false|# 0/false disables option
limitDisplay: 'none', // none|text|html|both
limitStop: false // true/false
}
});
*/
}
</script>
<div class="element element_input {container_class_li.join(' ')}" style={container_style}>
{#if type === 'email' || type === 'date' || type === 'number' || type === 'tel' || type === 'text' || type === 'time' || type === 'url' }
{#if (content_layout == 'label_start' && label)}
<label for={id} class={label_class_li.join(' ')} style={label_style}>{label}</label>
{/if}
<input {id} {name} class={class_li.join(' ')} {style} use:set_input_type {placeholder} {size} {pattern} {readonly} {disabled} {required} inputmode={input_mode} data-id_random={id_random} data-obj_type={obj_type} data-obj_prop_name={obj_prop_name} use:util.set_focus={focus} on:input={handle_oninput_dispatch} bind:value={value} />
{#if (content_layout != 'label_start' && label)}
<label for={id} class={label_class_li.join(' ')} style={label_style}>{label}</label>
{/if}
<span>{description}</span>
{:else if type === 'date_time' }
{#if (content_layout == 'label_start' && label)}
<span class={label_class_li.join(' ')} style={label_style}>{label}</span>
<!-- <label for={id} class={label_class_li.join(' ')} style={label_style}>{label}</label> -->
{/if}
<div class="element_input multipart {multipart_class_li.join(' ')}" style={multipart_style}>
{#if label_begin}
<label for={`${id}_date`} class={label_class_li.join(' ')} style={label_style}>{label_date}</label>
{/if}
<input id={id+'_date'} name={name+'_date'} {style} class={class_li.join(' ')} type="date" value={value_date} {placeholder} {readonly} {disabled} {required} data-id_random={id_random} data-obj_type={obj_type} data-obj_prop_name={obj_prop_name} on:input={handle_oninput_dispatch} />
{#if !label_begin}
<label for={`${id}_date`} class={label_class_li.join(' ')} style={label_style}>{label_date}</label>
{/if}
</div>
<div class="element_input multipart {multipart_class_li.join(' ')}" style={multipart_style}>
{#if label_begin}
<label for={`${id}_time`} class={label_class_li.join(' ')} style={label_style}>{label_time}</label>
{/if}
<input id={id+'_time'} name={name+'_time'} {style} class={class_li.join(' ')} type="time" value={value_time} {placeholder} {readonly} {disabled} {required} data-id_random={id_random} data-obj_type={obj_type} data-obj_prop_name={obj_prop_name} on:input={handle_oninput_dispatch} />
{#if !label_begin}
<label for={`${id}_time`} class={label_class_li.join(' ')} style={label_style}>{label_time}</label>
{/if}
</div>
{#if (content_layout != 'label_start' && label)}
<span class={label_class_li.join(' ')} style={label_style}>{label}</span>
<!-- <label for={id} class={label_class_li.join(' ')} style={label_style}>{label}</label> -->
{/if}
<span>{description}</span>
{:else if type === 'checkbox' }
{#if checkbox_none}
{#if !value}
{checked='checked'}
{/if}
<label>{checkbox_none_text}
<input {name} type="checkbox" value="" {readonly} {disabled} {required} {checked} on:input={handle_oninput_dispatch} />
</label>
{/if}
{#if checkbox_li.length}
{#if (content_layout == 'label_start' && label)}
<span class="input_container_label label_begin">{label}</span>
{/if}
{#each Object.entries(checkbox_li) as [li_key, li_value]}
{#if li_key.toString() === value.toString() }
<label>{li_value}
<input {name} type="checkbox" value="{li_key}" checked on:input={handle_oninput_dispatch}>
</label>
{:else}
<label>{li_value}
<input {name} type="checkbox" value="{li_key}" on:input={handle_oninput_dispatch}>
</label>
{/if}
{/each}
{#if (content_layout != 'label_start' && label)}
<span class="input_container_label label_end">{label}</span>
{/if}
{:else}
{#if label_begin}
<label for={id} class={label_class_li.join(' ')} style={label_style}>{label}</label>
{/if}
<input {id} {name} class={class_li.join(' ')} {style} type="checkbox" {value} {placeholder} {readonly} {disabled} {required} data-id_random={id_random} data-obj_type={obj_type} data-obj_prop_name={obj_prop_name} {checked} on:input={handle_oninput_dispatch} />
{/if}
<span>{description}</span>
{:else if type === 'radio' }
{#if radio_none}
{#if !value}
{checked='checked'}
{/if}
<label class={radio_option_class_li.join(' ')}>{@html radio_none_text}
<input {name} type="radio" value="" {readonly} {disabled} {required} {checked} on:input={handle_oninput_dispatch} />
</label>
{/if}
{#if radio_li}
{#if (content_layout == 'label_start' && label)}
<span class="input_container_label label_begin">{label}:</span>
{/if}
<span class="input_container_radio_options">
{#each Object.entries(radio_li) as [li_key, li_value]}
{#if value === null} <!-- If null then no option should be selected. -->
<label>{@html li_value}
<input {name} type="radio" bind:group={value} value="{li_key}" on:input={handle_oninput_dispatch}>
</label>
{:else if ( li_key.toString() === value.toString() || (li_key == 'true' && value == true) || (li_key == 'false' && value == false) ) }
<label>{@html li_value}
<input {name} type="radio" bind:group={value} value="{li_key}" checked on:input={handle_oninput_dispatch}> Z
</label>
{:else}
<label>{@html li_value}
<input {name} type="radio" bind:group={value} value="{li_key}" on:input={handle_oninput_dispatch}>
</label>
{/if}
<!-- <label>{@html li_value}
<input {name} type="radio" bind:group={value} value="{li_key}" on:input={handle_oninput_dispatch}>
</label> -->
{/each}
</span>
{#if !label_begin}
<span class="input_container_label label_end">{label}:</span>
{/if}
{:else}
{#if label_begin}
<label for={id} class={label_class_li.join(' ')} style={label_style}>{@html label}</label>
{/if}
<input {id} {name} class={class_li.join(' ')} {style} type="radio" {value} {placeholder} {readonly} {disabled} {required} data-id_random={id_random} data-obj_type={obj_type} data-obj_prop_name={obj_prop_name} {checked} on:input={handle_oninput_dispatch} />
{#if !label_begin}
<label for={id} class={label_class_li.join(' ')} style={label_style}>{@html label}</label>
{/if}
{/if}
<span>{description}</span>
{:else if type === 'textarea'}
{#if label_begin}
<label for={id} class={label_class_li.join(' ')} style={label_style}>{label}</label>
{/if}
{#if value_new_line}<br>{/if}
<textarea {id} {name} class={class_li.join(' ')} {style} bind:value={value} {placeholder} {readonly} {disabled} {required} {rows} {cols} data-id_random={id_random} data-obj_type={obj_type} data-obj_prop_name={obj_prop_name} on:input={handle_oninput_dispatch}></textarea>
<!-- rows="" cols="" maxlength="" -->
{#if !label_begin}
<label for={id} class={label_class_li.join(' ')} style={label_style}>{label}</label>
{/if}
<span>{description}</span>
{:else if type === 'hidden'}
<input {id} {name} class={class_li.join(' ')} type="hidden" bind:value={value} {placeholder} {readonly} {disabled} {required} data-id_random={id_random} data-obj_type={obj_type} data-obj_prop_name={obj_prop_name} />
{:else if type === 'select'}
{#if label_begin}
<label for={id} class={label_class_li.join(' ')} style={label_style}>
{label}
<!-- {#if value} <span class="label_select_value">{value}</span>{/if} -->
</label>
{/if}
<select {id} {name} class={class_li.join(' ')} {style} {readonly} {disabled} {required} data-id_random={id_random} data-obj_type={obj_type} data-obj_prop_name={obj_prop_name} on:input={handle_oninput_dispatch}>
{#if select_option_none}
<option value="">{select_option_none_text}</option>
{/if}
{#if select_option_li_lu_name}
<!-- <Select_element_lu lu_list_name={select_option_li_lu_name} params={select_option_li_lu_params} value_field_name={select_option_lu_value_field_name} text_field_name={select_option_lu_text_field_name} slct_value={value} /> -->
{:else}
{#each Object.entries(select_option_li) as [li_key, li_value]}
{#if value === null} <!-- If null then no option should be selected. -->
<option value="{li_key}">
{li_value}
</option>
{:else if li_key.toString() === value.toString() }
<option value="{li_key}" selected>
{li_value}
</option>
{:else}
<option value="{li_key}">
{li_value}
</option>
{/if}
{/each}
{/if}
</select>
{#if !label_begin}
<label for={id} class={label_class_li.join(' ')} style={label_style}>
{label}
{#if value} <span class="label_select_value">{value}</span>{/if}
</label>
{/if}
<span>{description}</span>
{/if}
<slot name="more_html">
</slot>
</div>
<style>
.container_inline {
display: inline;
}
</style>

View File

@@ -0,0 +1,584 @@
<script lang="ts">
import { onMount } from 'svelte';
import { clipboard } from '@skeletonlabs/skeleton';
// import { liveQuery } from "dexie";
import type { key_val } from '$lib/ae_stores';
import { ae_util } from '$lib/ae_utils/ae_utils';
import { api } from '$lib/api';
// import Element_ae_crud from '$lib/element_ae_crud.svelte';
// import Element_data_store from '$lib/element_data_store_v2.svelte';
// import { core_func } from '$lib/ae_core_functions';
import { ae_loc, ae_sess, ae_api, ae_trig, slct, slct_trigger } from '$lib/ae_stores';
import { db_events } from "$lib/db_events";
import { events_loc, events_sess, events_slct, events_trigger } from '$lib/ae_events_stores';
import { events_func } from '$lib/ae_events_functions';
export let container_class_li: string|Array<string> = [];
export let lq__event_file_obj_li: any;
export let link_to_type: string;
export let link_to_id: string;
export let allow_basic: boolean = false;
export let allow_moderator: boolean = false;
export let display_mode: string = 'default'; // 'default', 'compact', 'minimal', 'launcher'
// export let show_convert_btn: null|boolean = null;
// let ae_placeholder_li: key_val = {};
let ae_promises: key_val = {};
let ae_tmp: key_val = {};
ae_tmp.show__file_li = true;
ae_tmp.show__direct_download = false;
// let ae_triggers: key_val = {};
onMount(() => {
// console.log('Element - Manage Event File List');
console.log(`link_to_type: ${link_to_type}; link_to_id: ${link_to_id}`);
console.log(`allow_basic: ${allow_basic}; allow_moderator: ${allow_moderator}`);
});
</script>
<div
class="float-right flex flex-row items-center"
>
<button
type="button"
on:click={() => {
console.log('*** Refresh button clicked ***');
db_events.files.clear();
let params = {
qry__enabled: 'all',
qry__hidden: 'all',
}
events_func.load_ae_obj_li__event_file({
api_cfg: $ae_api,
for_obj_type: link_to_type,
for_obj_id: link_to_id,
params: params,
try_cache: true
});
// ae_tmp.show__file_li = false;
// console.log(`$lq__event_file_obj_li:`, $lq__event_file_obj_li);
// $slct_trigger = 'load__event_file_obj_li';
// ae_tmp.show__file_li = true;
}}
class="btn btn-sm p-1 m-1 variant-soft-tertiary hover:variant-ghost-warning transition hover:transition-all *:hover:inline"
class:hidden={!$ae_loc.edit_mode || !$ae_loc.authenticated_access}
title="Refresh the list of files"
>
<span class="fas fa-sync-alt m-1"></span>
<div class="hidden">
Files
</div>
</button>
<button
type="button"
on:click={() => {
console.log('*** Show Alt Download button clicked ***');
ae_tmp.show__direct_download = !ae_tmp.show__direct_download;
}}
class="btn btn-sm p-1 m-1 variant-soft-tertiary hover:variant-ghost-warning transition hover:transition-all *:hover:inline"
class:hidden={!$ae_loc.edit_mode || !$ae_loc.trusted_access}
title="Toggle direct download link and copy link button"
>
<span class="fas fa-download m-1"></span>
<div class="hidden">
{ae_tmp.show__direct_download ? 'Alt On' : 'Alt Download Off'}
</div>
</button>
</div>
<section class="svelte_component event_file_uploaded_manage {container_class_li}"
class:text-sm={display_mode != 'default'}
>
<h3
class="h6"
class:hidden={!$lq__event_file_obj_li?.length || display_mode != 'default'}
>
Manage Files:
<span class="font-bold bg-success-100 px-4 border rounded-lg border-success-200"
title="Files for {link_to_type ?? '-- not set --'}: {link_to_id ?? '-- not set --'} (files: {$lq__event_file_obj_li?.length ?? 'None'})"
>
<span class="fas fa-folder-open mx-1"></span>
{@html $lq__event_file_obj_li ? `${$lq__event_file_obj_li.length}&times;` : '-- none --'}
</span>
</h3>
{#if $lq__event_file_obj_li && $lq__event_file_obj_li.length}
<div class="overflow-auto w-full">
<table class="table-auto w-full">
{#if display_mode === 'default'}
<thead>
<tr>
<th class="text-center">Download File</th>
{#if display_mode === 'default'}
<th
class="text-center"
class:hidden={!allow_basic && !$ae_loc.trusted_access}
>Options</th>
{/if}
{#if display_mode === 'default'}
<th
class="text-center"
class:hidden={!allow_basic && !$ae_loc.trusted_access}
>Status</th>
{/if}
<th class="text-center">Meta</th>
</tr>
</thead>
{/if}
<tbody>
{#each $lq__event_file_obj_li as event_file_obj}
<tr
class="ae_obj obj_event_file border-t border-b border-gray-200 hover:bg-gray-50 hover:border-gray-300"
class:dim={event_file_obj?.hide}
>
<td class="event_file__file align-middle">
{#if $events_sess.pres_mgmt?.show_field_edit__filename != event_file_obj.event_file_id_random}
<button
disabled={!allow_basic && !allow_moderator && !$ae_loc.trusted_access}
on:click={() => {
// ae_promises[event_file_obj.event_file_id_random]
ae_promises[event_file_obj.event_file_id_random] = api.download_hosted_file({
api_cfg: $ae_api,
hosted_file_id: event_file_obj.hosted_file_id_random,
return_file: true,
filename: event_file_obj.filename,
auto_download: true,
log_lvl: 0
});
// window.postMessage({ type: 'download_event_file', event_file_id: event_file_obj.event_file_id_random, filename: event_file_obj.filename, auto_download: true }, '*');
}}
class="btn btn-sm lg:btn-md variant-soft-primary hover:variant-filled-primary min-w-72 lg:min-w-96"
title={`Download this file:\n${event_file_obj.filename}\n[API] SHA256: ${event_file_obj.hash_sha256.slice(0, 10)}... Hosted ID: ${event_file_obj.hosted_file_id_random} Event File ID: ${event_file_obj.event_file_id_random}`}
>
{#await ae_promises[event_file_obj.event_file_id_random]}
<span class="fas fa-spinner fa-spin mx-1"></span>
<span class="">
Downloading
{#if $ae_sess.api_download_kv[event_file_obj.hosted_file_id_random]}
{$ae_sess.api_download_kv[event_file_obj.hosted_file_id_random].percent_completed}%
{/if}
:
</span>
{:then}
<!-- <span class="fas fa-download mx-1"></span> -->
<span class="fas fa-{ae_util.file_extension_icon(event_file_obj.extension)}"></span>
<!-- <span class="text-sm">
Download:
</span> -->
{/await}
<span class="grow">
{ae_util.shorten_filename({filename: event_file_obj.filename, max_length: 30})}
</span>
<span
class="badge variant-glass-success hover:variant-filled-success text-sm"
class:hidden={!event_file_obj.file_purpose}
>
{event_file_obj.file_purpose}
</span>
</button>
<a
href="{$ae_api.base_url}/event/file/{event_file_obj.event_file_id_random}/download?filename={event_file_obj.filename}&x_no_account_id_token=direct-download"
class="btn btn-sm variant-soft-secondary m-0.5 *:hover:inline"
class:hidden={!ae_tmp.show__direct_download}
title={`Download this file:\n${event_file_obj.filename}\n[API] SHA256: ${event_file_obj.hash_sha256.slice(0, 10)}... Hosted ID: ${event_file_obj.hosted_file_id_random} Event File ID: ${event_file_obj.event_file_id_random}`}
>
<span class="fas fa-download mx-1"></span>
<div class="hidden">
Download
</div>
</a>
<button
type="button"
use:clipboard={encodeURI(`${$ae_api.base_url}/event/file/${event_file_obj.event_file_id_random}/download?filename=${event_file_obj.filename}&x_no_account_id_token=direct-download`)}
class="btn btn-sm variant-soft-secondary m-0.5 *:hover:inline"
class:hidden={!ae_tmp.show__direct_download}
title="Copy the direct download file link to the clipboard."
>
<span class="fas fa-copy mx-1"></span>
<div class="hidden">
Copy Link
</div>
</button>
{:else}
<!-- Show change filename input field here -->
<span
class="flex flex-col gap-1 text-sm"
>
<input
type="text"
size="12"
placeholder="Filename"
bind:value="{$events_sess.pres_mgmt.tmp_val__filename_no_ext}"
data-original_value="{event_file_obj.filename}"
class="input min-w-72 lg:min-w-96 text-sm bg-warning-100"
title="Rename this file. No extension."
>
{#if $events_sess.pres_mgmt.tmp_val__filename_no_ext.trim() != event_file_obj.filename_no_ext}
<button
on:click={async () => {
let new_filename = $events_sess.pres_mgmt.tmp_val__filename_no_ext.trim()
// Remove possible double extension
new_filename = new_filename.replace('.'+event_file_obj.extension, '');
// Add the extension back
new_filename = new_filename + '.' + event_file_obj.extension;
// Remove any double dots
new_filename = new_filename.replace(/\.\./g, '.');
let event_file_data = {
filename: new_filename,
};
ae_promises.update__event_file_obj = events_func.update_ae_obj__event_file({
api_cfg: $ae_api,
event_file_id: event_file_obj.event_file_id_random,
data_kv: event_file_data,
log_lvl: 0
})
.then (function (update_results) {
console.log(`Update results:`, update_results);
$events_sess.pres_mgmt.show_field_edit__filename = false;
});
}}
class="btn btn-sm variant-glass-tertiary hover:variant-soft-success"
title="Save changes"
>
{#await ae_promises.update__event_file_obj}
<span class="fas fa-spinner fa-spin mx-1"></span>
<span class="">Saving {event_file_obj.extension}</span>
{:then}
<span class="fas fa-save mx-1"></span>
Save {event_file_obj.extension} filename?
{/await}
</button>
{/if}
</span>
{/if}
</td>
{#if display_mode === 'default'}
<td
class="event_file__options"
class:hidden={!allow_basic && !$ae_loc.trusted_access}
>
<div class="flex flex-col gap-1 text-sm">
<button
disabled={!allow_basic && !$ae_loc.trusted_access}
on:click={() => {
if ($events_sess.pres_mgmt.show_field_edit__filename == event_file_obj.event_file_id_random) {
$events_sess.pres_mgmt.tmp_val__filename_no_ext = '';
$events_sess.pres_mgmt.show_field_edit__filename = false;
} else {
$events_sess.pres_mgmt.tmp_val__filename_no_ext = event_file_obj.filename_no_ext;
$events_sess.pres_mgmt.show_field_edit__filename = event_file_obj.event_file_id_random;
}
}}
class="btn btn-sm variant-glass-tertiary hover:variant-soft-success"
class:variant-glass-warning={$events_sess.pres_mgmt.show_field_edit__filename == event_file_obj.event_file_id_random}
title={`Rename this file? "${event_file_obj.filename}"`}
>
<span class="fas fa-edit mx-1"></span>
{#if $events_sess.pres_mgmt?.show_field_edit__filename == event_file_obj.event_file_id_random}
Cancel?
{:else}
Rename
{/if}
</button>
<button
disabled={!allow_basic && !$ae_loc.trusted_access}
on:click={async () => {
let event_file_data = {
hide: !event_file_obj.hide,
};
ae_promises.update__event_file_obj = events_func.update_ae_obj__event_file({
api_cfg: $ae_api,
event_file_id: event_file_obj.event_file_id_random,
data_kv: event_file_data,
log_lvl: 0
})
.then (function (update_results) {
console.log(`Update results:`, update_results);
let params = {
qry__enabled: 'all',
qry__hidden: 'all',
}
events_func.load_ae_obj_li__event_file({
api_cfg: $ae_api,
for_obj_type: link_to_type,
for_obj_id: link_to_id,
params: params,
try_cache: true
});
});
}}
class="btn btn-sm variant-glass-tertiary hover:variant-soft-success"
title="Hide this file from the presentation launcher"
>
<!-- Users see this as the "Archive" option button -->
<!-- {@html (event_file_obj?.hide ? '<span class="fas fa-archive m-1"></span> Unarchive' : '<span class="fas fa-archive m-1"></span> Archive')} -->
{#await ae_promises.update__event_file_obj}
<span class="fas fa-spinner fa-spin mx-1"></span>
<span class="">Saving {event_file_obj.extension}</span>
{:then}
{#if event_file_obj.hide}
<span class="fas fa-eye m-1"></span> Unhide File
{:else}
<span class="fas fa-eye-slash m-1"></span> Hide
{/if}
<!-- {@html (event_file_obj?.hide ? '<span class="fas fa-eye m-1"></span> Unhide?' : '<span class="fas fa-eye-slash m-1"></span> Hide?')} -->
<!-- <span class="fas fa-save mx-1"></span>
Save {event_file_obj.extension} filename? -->
{/await}
</button>
<button
disabled={!allow_basic && !$ae_loc.trusted_access}
on:click={async () => {
if (!confirm(`Are you sure you want to delete this file?\n${event_file_obj.filename} [${event_file_obj.event_file_id_random}]`)) {return false;}
// ae_promises[event_file_obj.event_file_id_random] = handle_delete__event_file({event_file_id: event_file_obj.event_file_id_random});
ae_promises.delete__event_file_obj = await events_func.delete_ae_obj_id__event_file({
api_cfg: $ae_api,
event_file_id: event_file_obj.event_file_id_random,
log_lvl: 1
})
}}
class="btn btn-sm variant-glass-tertiary hover:variant-soft-success"
title="Delete this file"
>
<span class="fas fa-trash-alt mx-1"></span>
<!-- <span class="fas fa-minus mx-1"></span> -->
Delete
</button>
</div>
</td>
{/if}
{#if display_mode === 'default'}
<td
class="event_file__status"
class:hidden={!allow_basic && !$ae_loc.trusted_access}
>
<div class="flex flex-col gap-1 items-center text-sm">
<div class="">
{#if event_file_obj.open_in_os == 'win'}
MS Windows <span class="fab fa-windows"></span>
{:else if event_file_obj.open_in_os == 'mac'}
Apple macOS <span class="fab fa-apple"></span>
{/if}
</div>
<!-- Select from options for the purpose of this file -->
<div>
<label
for="file_purpose"
class="text-sm mx-1 hidden"
>
Purpose:
</label>
<select
id="file_purpose"
name="file_purpose"
disabled={!allow_basic && !allow_moderator && !$ae_loc.trusted_access}
value={event_file_obj.file_purpose}
on:change={e => {
// ae_tmp[event_file_obj.event_file_id_random].file_purpose = e.target.value;
console.log(`Selected file_purpose: ${e.target.value}`);
let event_file_data = {
event_file_id_random: event_file_obj.event_file_id_random,
file_purpose: e.target.value,
};
events_func.update_ae_obj__event_file({
api_cfg: $ae_api,
event_file_id: event_file_obj.event_file_id_random,
data_kv: event_file_data,
log_lvl: 1
})
.then (function (update_results) {
console.log(`Update results:`, update_results);
$slct_trigger = 'load__event_file_obj_li';
});
// ae_triggers.update_event_file_purpose = true;
}}
class="select min-w-fit max-w-fit text-sm mx-1 border border-gray-300 rounded-md p-1 hover:border-gray-400"
>
<option value={null} selected={!event_file_obj.file_purpose} class="text-xs">-- purpose not set --</option>
{#if $events_loc.pres_mgmt?.file_purpose_option_kv}
{#each Object.entries($events_loc.pres_mgmt.file_purpose_option_kv) as [key, file_purpose_option]}
<option
value={key} selected={event_file_obj.file_purpose === key}
disabled={file_purpose_option?.disabled}
class:hidden={file_purpose_option?.hidden}
>
{file_purpose_option?.name}
</option>
{/each}
{/if}
<!-- <option value="outline" selected={event_file_obj.file_purpose === 'outline'}>1. Outline</option> -->
<!-- <option value="draft" selected={event_file_obj.file_purpose === 'draft'}>2. Draft</option> -->
<!-- <option value="final" selected={event_file_obj.file_purpose === 'final'}>3. Final</option> -->
<!-- <option value="supporting">X. Supporting File (audio, video, data, etc)</option> -->
<!-- <option value="handout">X. Handout</option> -->
<!-- <option value="other">X. Other</option> -->
<!-- <option value="poster">Final - Poster</option> -->
<!-- <option value="presentation">Final - Presentation</option> -->
<!-- Shows in session room -->
</select>
</div>
</div>
</td>
{/if}
<td class="event_file_info file_meta text-gray-500">
<div
class="flex flex-col gap-0.5 text-xs"
>
<!-- {event_file_obj.hosted_file_content_type} -->
<span class="w-full flex flex-col lg:flex-row justify-between">
<span
class:hidden={display_mode != 'default'}
>
Type:
<strong>{event_file_obj.extension} <span class="fas fa-{ae_util.file_extension_icon(event_file_obj.extension)}"></span>
</strong>
<!-- {#if event_file_obj.open_in_os == 'win'}
<strong>
MS Windows <span class="fab fa-windows"></span>
</strong>
{:else if event_file_obj.open_in_os == 'mac'}
<strong>
Apple macOS <span class="fab fa-apple"></span>
</strong>
{/if} -->
</span>
<span>
<span
class:hidden={display_mode != 'default'}
>
Size:
</span>
<strong>{ae_util.format_bytes(event_file_obj.file_size)}</strong>
</span>
</span>
<span class="w-full flex flex-col lg:flex-row justify-between">
<span title="SHA 256: {event_file_obj.hash_sha256}">
<span
class:hidden={display_mode != 'default'}
>
Hash:
</span>
<strong
class:font-normal={display_mode != 'default'}
>{event_file_obj.hash_sha256.slice(0, 10)}&mldr;</strong>
</span>
<span
class:hidden={!$ae_loc.administrator_access || display_mode != 'default'}>
<span
class:hidden={display_mode != 'default'}
>
ID:
</span>
<strong>{event_file_obj.hosted_file_id_random}</strong>
</span>
</span>
<!-- If this file was uploaded (created) within the last 15 minutes we want to highlight it in blue. -->
<span
class:bg-yellow-200={ae_util.is_datetime_recent({datetime: event_file_obj?.created_on, minutes: 30})}
class:bg-green-200={ae_util.is_datetime_recent({datetime: event_file_obj?.created_on, minutes: 240})}
class:bg-blue-200={ae_util.is_datetime_recent({datetime: event_file_obj?.created_on, minutes: 2880})}
>
{#if display_mode == 'default'}
<!-- <span class="fas fa-cloud-upload-alt mx-1"></span> -->
<!-- Uploaded: -->
<!-- <span class="fas fa-calendar-day mx-1"></span> -->
<span class="fas fa-clock mx-1"></span>
<strong>
{ae_util.iso_datetime_formatter(event_file_obj.created_on, 'dddd')}
</strong>
{ae_util.iso_datetime_formatter(event_file_obj.created_on, 'date_iso')}
at
<strong>{ae_util.iso_datetime_formatter(event_file_obj.created_on, 'time_12_short_no_leading')}</strong>
<!-- {event_file_obj.updated_on} -->
{:else}
<!-- <span class="fas fa-calendar-day mx-1"></span> -->
<strong>
{ae_util.iso_datetime_formatter(event_file_obj.created_on, 'date_short')}
<!-- at -->
<strong>{ae_util.iso_datetime_formatter(event_file_obj.created_on, 'time_12_short_no_leading')}</strong>
</strong>
{/if}
</span>
</div>
</td>
</tr>
{/each}
</tbody>
</table>
</div>
{:else}
<p
class="w-96 text-center text-gray-500"
class:hidden={display_mode != 'default'}
>
No files uploaded to display
</p>
{/if}
</section>
<style>
</style>

View File

@@ -0,0 +1,59 @@
<script lang="ts">
// import { onMount } from 'svelte';
// import { clipboard } from '@skeletonlabs/skeleton';
import { liveQuery } from "dexie";
import type { key_val } from '$lib/ae_stores';
// import { ae_util } from '$lib/ae_utils/ae_utils';
// import { api } from '$lib/api';
// import Element_ae_crud from '$lib/element_ae_crud.svelte';
// import Element_data_store from '$lib/element_data_store_v2.svelte';
import Element_manage_event_file_li from '$lib/element_manage_event_file_li.svelte';
// import { core_func } from '$lib/ae_core_functions';
import { ae_loc, ae_sess, ae_api, ae_trig, slct, slct_trigger } from '$lib/ae_stores';
import { db_events } from "$lib/db_events";
// import { events_loc, events_sess, events_slct, events_trigger } from '$lib/ae_events_stores';
// import { events_func } from '$lib/ae_events_functions';
export let container_class_li: string|Array<string> = [];
export let link_to_type: string;
export let link_to_id: string;
export let allow_basic: boolean = false;
export let allow_moderator: boolean = false;
export let display_mode: string = 'default'; // 'default', 'compact', 'minimal', 'launcher'
// export let show_convert_btn: null|boolean = null;
// let ae_placeholder_li: key_val = {};
// let ae_promises: key_val = {};
let ae_tmp: key_val = {};
ae_tmp.show__file_li = true;
ae_tmp.show__direct_download = false;
// let ae_triggers: key_val = {};
let dq__where_val: string = `${link_to_type}_id_random`;
let dq__where_eq_val: string = link_to_id;
// This should include all files that are associated with an object (event, location, session, presenter, etc.)
// I am not sure why, but doing reverse() and then sortBy() seems to sort in descending order.
let lq__event_file_obj_li = liveQuery(
async () => await db_events.files
.where(dq__where_val)
.equals(dq__where_eq_val)
.reverse()
.sortBy('created_on')
// .toArray()
);
</script>
<Element_manage_event_file_li
link_to_type={link_to_type}
link_to_id={link_to_id}
lq__event_file_obj_li={lq__event_file_obj_li}
allow_basic={allow_basic}
allow_moderator={allow_moderator}
container_class_li={container_class_li}
display_mode={display_mode}
/>

View File

@@ -0,0 +1,69 @@
<script lang="ts">
// import { onMount } from 'svelte';
// import { clipboard } from '@skeletonlabs/skeleton';
import { liveQuery } from "dexie";
import type { key_val } from '$lib/ae_stores';
// import { ae_util } from '$lib/ae_utils/ae_utils';
// import { api } from '$lib/api';
// import Element_ae_crud from '$lib/element_ae_crud.svelte';
// import Element_data_store from '$lib/element_data_store_v2.svelte';
import Element_manage_event_file_li from '$lib/element_manage_event_file_li.svelte';
// import { core_func } from '$lib/ae_core_functions';
import { ae_loc, ae_sess, ae_api, ae_trig, slct, slct_trigger } from '$lib/ae_stores';
import { db_events } from "$lib/db_events";
// import { events_loc, events_sess, events_slct, events_trigger } from '$lib/ae_events_stores';
// import { events_func } from '$lib/ae_events_functions';
export let container_class_li: string|Array<string> = [];
export let link_to_type: string;
export let link_to_id: string;
export let allow_basic: boolean = false;
export let allow_moderator: boolean = false;
export let display_mode: string = 'default'; // 'default', 'compact', 'minimal', 'launcher'
// export let show_convert_btn: null|boolean = null;
// let ae_placeholder_li: key_val = {};
// let ae_promises: key_val = {};
let ae_tmp: key_val = {};
ae_tmp.show__file_li = true;
ae_tmp.show__direct_download = false;
// let ae_triggers: key_val = {};
let dq__where_val: string = `for_type`;
let dq__where_eq_val: string = link_to_type;
let dq__where_for_id_eq_val: string = link_to_id;
// This should only include files that are directly linked to an object (event, location, session, presenter, etc.).
// I am not sure why, but doing reverse() and then sortBy() seems to sort in descending order.
let lq__event_file_obj_li = liveQuery(
async () => await db_events.files
.where(dq__where_val)
.equals(dq__where_eq_val)
.and(file => file.for_id_random == dq__where_for_id_eq_val)
.reverse()
.sortBy('created_on')
// .toArray()
);
</script>
{#await lq__event_file_obj_li}
<p>Loading...</p>
{:then lq__event_file_obj_li}
<Element_manage_event_file_li
link_to_type={link_to_type}
link_to_id={link_to_id}
lq__event_file_obj_li={lq__event_file_obj_li}
allow_basic={allow_basic}
allow_moderator={allow_moderator}
container_class_li={container_class_li}
display_mode={display_mode}
/>
{:catch error}
<p style="color: red;">{error.message}</p>
{/await}

View File

@@ -0,0 +1,146 @@
<script lang="ts">
import { onMount } from 'svelte';
// This (ae) is only used for utilities
// import { ae } from 'aether_npm_lib';
import { ae_util } from '$lib/ae_utils/ae_utils';
// These (slct_*) are only used internally for this component. Not needed???
// import { slct_obj_id, slct_obj_li_type, slct_obj_type } from '../admin/stores_admin.js';
// Should these slct_* be exported???
let slct_obj_id = null;
let slct_obj_li_type = null;
let slct_obj_type = null;
export let row_header: boolean = false;
export let primary_obj_li_type: string = slct_obj_li_type; // account, person, user, event, event_session, membership_person
export let obj = null;
console.log(obj);
console.log(typeof obj);
onMount(() => {
console.log('** Element Mounted: ** Element Object Table Row');
if (obj) {
console.log('Table Row Object:', obj);
// console.log(typeof obj);
} else {
return false;
}
});
/* BEGIN: Handle requests (archive, create, hide, remove, select, update, POST, PATCH, GET, DELETE) */
/* END: Handle requests (archive, create, hide, remove, select, update, POST, PATCH, GET, DELETE) */
/* BEGIN: Handle other local actions (show/hide form, process data) */
/* END: Handle other local actions (show/hide form, process data) */
/* BEGIN: Handle children events (archived, canceled, closed, created, deleted, hidden, updated) */
/* END: Handle children events (archived, canceled, closed, created, deleted, hidden, updated) */
</script>
<tr>
{#if obj != null && typeof obj == 'object'}
{#each Object.entries(obj) as [obj_prop_name, obj_prop_value]}
<!-- NEED TO ADD A CHECK IF:
NOTE:
NOTE:
obj.id_random and obj.name then replace the ID field column with a link using obj.name
This should probably go outside/before this tr loop.
NOTE:
NOTE:
-->
{#if obj_prop_name.endsWith('_id_random') || obj_prop_name == 'for_type' || obj_prop_name == 'for_id'}
{#if row_header}
<th data-obj_type={primary_obj_li_type} data-obj_prop_name={obj_prop_name} on:click={() => primary_obj_li_type=obj_prop_name.replace('_id_random', '')}>
{ae_util.set_obj_prop_display_name({prop_name: obj_prop_name, obj_type: primary_obj_li_type})}
</th>
{:else}
<td
data-obj_type={primary_obj_li_type}
data-obj_prop_name={obj_prop_name}
on:click={() => {
slct_obj_type=obj_prop_name.replace('_id_random', '');
slct_obj_id=obj_prop_value;
}}
on:keypress={() => {
slct_obj_type=obj_prop_name.replace('_id_random', '');
slct_obj_id=obj_prop_value;
}}
>
<!-- {obj_prop_value} -->
<!-- {#if (obj_prop_value && obj_prop_value.length > 25)}
{obj_prop_value.substring(0,25)}
{:else} -->
{#if obj_prop_value}
<a href="/{ae_util.return_obj_type_path({obj_type_prop_name: obj_prop_name})}/{obj_prop_value}">
{obj_prop_value.substring(0,25)}
</a>
{:else}
<!-- {obj_prop_value} -->
<span class="fs_smaller">-- None --</span>
{/if}
</td>
{/if}
{:else if obj_prop_name.endsWith('[URL]')}
{#if row_header}
<th data-obj_type={primary_obj_li_type} data-obj_prop_name={obj_prop_name} on:click={() => primary_obj_li_type=obj_prop_name.replaceAll('[URL]', '')}>
{ae_util.set_obj_prop_display_name({prop_name: obj_prop_name.replaceAll('[URL]', ''), obj_type: primary_obj_li_type})}
</th>
{:else}
<td
data-obj_type={primary_obj_li_type}
data-obj_prop_name={obj_prop_name}
on:click={() => {
slct_obj_type=obj_prop_name.replaceAll('[URL]', '');
slct_obj_id=obj_prop_value;
}}
on:keypress={() => {
slct_obj_type=obj_prop_name.replaceAll('[URL]', '');
slct_obj_id=obj_prop_value;
}}
>
<a href="{obj_prop_value}">{obj_prop_value}</a>
</td>
{/if}
{:else}
{#if row_header}
<th data-obj_type={primary_obj_li_type} data-obj_prop_name={obj_prop_name}>
{ae_util.set_obj_prop_display_name({prop_name: obj_prop_name, obj_type: primary_obj_li_type})}
</th>
{:else}
<td data-obj_type={primary_obj_li_type} data-obj_prop_name={obj_prop_name}>
{#if (obj_prop_value)}
{#if (obj_prop_value && obj_prop_value.length > 25)}
{obj_prop_value.substring(0,25)} ...
{:else}
{obj_prop_value}
{/if}
{:else}
<span class="fs_smaller">-- None --</span>
{/if}
</td>
{/if}
{/if}
<!-- <td data-obj_type={primary_obj_li_type} data-obj_prop_name={obj_prop_name}>{obj_prop_value}</td> -->
{/each}
{:else}
-- Not Set --
{/if}
</tr>
<style lang="postcss">
</style>

View File

@@ -0,0 +1,543 @@
<script lang="ts">
// *** Import Svelte core
import { createEventDispatcher, onDestroy, onMount } from 'svelte';
// import 'html5-qrcode';
import {Html5Qrcode, Html5QrcodeScannerState, Html5QrcodeSupportedFormats} from 'html5-qrcode';
// *** Import Aether core variables and functions
import { api } from '$lib/api';
import { ae_api } from '$lib/ae_stores';
// *** Import Aether core components
// import Element_input from './element_input.svelte';
// import ae from '/element_input.svelte';
// import Input_element from '/element_input.svelte';
// *** Import Aether module variables and functions
// *** Import Aether module components
// *** Export/Exposed variables and functions for component
export let start_qr_scanner: boolean = true;
export let show_pause_btn: boolean = false; // pause and resume buttons
export let show_qr_manual_text_entry_option: boolean = false;
export let show_qr_manual_badge_id_entry_option: boolean = false;
export let show_qr_scan_result: boolean = true;
export let qr_fps = 15;
export let qr_viewfinder_width = 275; // 275 seems good... Need to not let the this be larger than the container which changes based on the width of the screen/window.
export let qr_facing_mode = 'environment'; // environment, user, { exact: 'environment'}, { exact: 'user'}
// *** Set initial variables
let scanning_status: string = 'not_started';
let qr_scan_result: null|string = null;
let qr_found_text: null|string = null;
let qr_entered_text: null|string = null;
let qr_entered_badge_id: null|string = null;
let show_qr_manual_entry: null|boolean = null;
let disable_submit_badge_id_btn: boolean = true;
let user_media_status = 'not_requested';
// let max_results: number = 50;
const dispatch = createEventDispatcher();
let html5_qr_code: any|null|string = null;
// let html5_qr_code = new Html5Qrcode(
// 'qr_scanner_viewfinder', { formatsToSupport: [ Html5QrcodeSupportedFormats.QR_CODE ] }
// );
// let qr_scan_cfg = { fps: 10, qrbox: 400 }; // default was 250 and using 300 when 600px
let qr_scan_cfg = { fps: qr_fps, qrbox: qr_viewfinder_width }; // 275 seems good... Need to not let the this be larger than the container which changes based on the width of the screen/window.
// let mounted = false;
onMount(() => {
console.log('** Element Mounted: ** QR Scanner');
// NOTE: We only want to trigger the scanning to start after the page has fully loaded.
navigator.mediaDevices.getUserMedia({video: true})
.then(successCallback, errorCallback);
// NOTE: This can only be done after the page has fully loaded.
// if (start_qr_scanner) {
// handle_start_qr_scanning();
// }
});
onDestroy(async () => {
console.log('** Element Destroyed: ** QR Scanner');
qr_scan_result = null;
qr_found_text = null;
await handle_stop_qr_scanning();
});
var successCallback = function(error: any) {
console.log('Camera access allowed');
user_media_status = 'allowed';
// let subject = 'Camera Access Allowed';
// let message = error;
// send_init_confirm_email(subject, message);
dispatch('qr_camera', {
status: 'allowed',
});
// NOTE: This can only be done after the page has fully loaded.
if (start_qr_scanner) {
handle_start_qr_scanning();
}
};
var errorCallback = function(error: any) {
if (error.name == 'NotAllowedError') {
console.log('Camera access not allowed!');
user_media_status = 'denied';
// let subject = 'Camera Access Denied';
// let message = error;
// send_init_confirm_email(subject, message);
dispatch('qr_camera', {
status: 'denied',
});
}
};
// $: if (mounted && start_qr_scanner) {
// console.log('START QR SCANNING');
// handle_start_qr_scanning();
// } else if (mounted && !start_qr_scanner) {
// console.log('STOP QR SCANNING');
// handle_stop_qr_scanning();
// }
async function handle_start_qr_scanning() {
console.log('*** handle_start_qr_scanning() ***');
if (user_media_status == 'denied') {
console.log('Camera access not allowed!');
return;
} else if (user_media_status == 'not_requested') {
console.log('Camera access not requested yet!');
return;
}
qr_scan_result = null;
qr_found_text = null;
if (html5_qr_code) {
console.log('html5_qr_code object found. Clearing and creating new Html5Qrcode...');
// html5_qr_code.clear();
// document.getElementById('qr_scanner_viewfinder').classList.remove('d_none');
html5_qr_code = new Html5Qrcode(
'qr_scanner_viewfinder', { formatsToSupport: [ Html5QrcodeSupportedFormats.QR_CODE ] }
);
} else {
console.log('html5_qr_code not found. Creating new Html5Qrcode...');
html5_qr_code = new Html5Qrcode(
'qr_scanner_viewfinder', { formatsToSupport: [ Html5QrcodeSupportedFormats.QR_CODE ] }
);
}
if (html5_qr_code.getState() == Html5QrcodeScannerState.NOT_STARTED) {
// console.log('Scanner is not started');
return await html5_qr_code.start({ facingMode: qr_facing_mode }, qr_scan_cfg, handle_qr_scan_success, handle_qr_scan_error)
.then((ignore: any) => {
console.log('Scanning has started');
scanning_status = 'scanning';
// let subject = 'QR Scanning Started';
// let message = ignore;
// send_init_confirm_email(subject, message);
return true;
}).catch((err) => {
console.log('There was an error while trying to start the QR scanner');
scanning_status = 'start_error';
let subject = 'QR Scanning Start Error';
let message = err;
send_init_confirm_email(subject, message);
return false;
});
} else {
console.log('Scanner is already started');
return;
}
}
function handle_pause_qr_scanning() {
if (html5_qr_code && html5_qr_code.getState() != Html5QrcodeScannerState.SCANNING) {
console.log('Scanner is not scanning!');
return;
}
html5_qr_code.pause();
scanning_status = 'paused';
}
function handle_resume_qr_scanning() {
if (html5_qr_code && html5_qr_code.getState() != Html5QrcodeScannerState.PAUSED) {
console.log('Scanner is not paused!');
return;
}
document.getElementById('qr_scanner_viewfinder').classList.remove('d_none');
html5_qr_code.resume();
scanning_status = 'scanning';
}
async function handle_stop_qr_scanning() {
start_qr_scanner = false;
if (!html5_qr_code) {
console.log('html5_qr_code object found. Nothing to stop?');
return false;
}
let state = html5_qr_code.getState();
console.log('html5_qr_code state:', state);
if (state == Html5QrcodeScannerState.NOT_STARTED) {
console.log('Scanner is not started');
return;
}
if (state == Html5QrcodeScannerState.PAUSED || state == Html5QrcodeScannerState.SCANNING) {
console.log('Scanner is not started');
await html5_qr_code.stop()
scanning_status = 'not_started';
return;
}
await html5_qr_code.clear();
return true;
// html5_qr_code.pause();
// return html5_qr_code.stop()
// .then((ignore) => {
// console.log('Scanning has stopped');
// // document.getElementById('qr_scanner_viewfinder').classList.add('d_none');
// scanning_status = 'not_started';
// }).then((ignore) => {
// // html5_qr_code = null;
// // html5_qr_code.clear();
// }).catch((err) => {
// console.log('There was an error while trying to stop the scanning');
// return false;
// });
// html5_qr_code = null;
}
// Callback function for QrcodeSuccessCallback (decodedText: string, result: Html5QrcodeResult)
function handle_qr_scan_success(decoded_text, decoded_result) {
console.log('*** handle_qr_scan_success() ***');
console.log(`QR scanned = ${decoded_text}`, decoded_result);
qr_scan_result = decoded_text; // NOTE: decoded_result is not currently used by html5-qrcode
qr_found_text = decoded_text;
dispatch('qr_scan_result', {
result: qr_scan_result, // This text will need to be parsed to get more info.
text: qr_found_text, // This text will need to be parsed to get more info.
entry_method: 'QR',
});
// handle_pause_qr_scanning();
handle_stop_qr_scanning();
}
// Callback function for QrcodeErrorCallback (errorMessage: string, error: Html5QrcodeError)
// NOTE: Most of the time this is normal and not an actual error. It just did not find something to scan.
function handle_qr_scan_error(qr_error_message, qr_code_error) {
// console.log('*** handle_qr_scan_error() ***');
if (qr_code_error.type) {
console.log(`Error scanning code = ${qr_error_message}`, qr_code_error);
return;
}
}
$: if ( qr_entered_badge_id && qr_entered_badge_id.length >= 11 && qr_entered_badge_id && qr_entered_badge_id.length <= 14) {
disable_submit_badge_id_btn = false;
} else {
disable_submit_badge_id_btn = true;
}
function handle_qr_manual_entry() {
console.log('*** handle_qr_manual_entry() ***');
if (qr_entered_text) {
console.log(`QR entered text = ${qr_entered_text}`);
} else if (qr_entered_badge_id) {
console.log(`QR entered badge ID = ${qr_entered_badge_id}`);
qr_entered_text = `OBJ:ot:event_badge,oi:${qr_entered_badge_id}`;
console.log(`Parse to proper QR badge ID = ${qr_entered_text}`);
}
// html5_qr_code.stop().then((ignore) => {
// console.log('Scanning has stopped');
// document.getElementById('qr_scanner_viewfinder').classList.add('d_none');
// }).catch((err) => {
// console.log('There was an error while trying to stop the scanning');
// });
qr_scan_result = qr_entered_text;
dispatch('qr_scan_result', {
result: qr_scan_result,
entry_method: 'manual',
});
qr_scan_result = null;
qr_entered_text = null;
}
function send_init_confirm_email(subject, message) {
console.log(`*** send_init_confirm_email() *** ${subject}`);
let to_email = 'scott.idem+skdev@oneskyit.com';
// let origin_url = encodeURI(`${data.url.origin}`);
let full_subject = `${subject} Aether QR Scanner Debugging`;
let body_html = `
<div>Scott,
<p>This is an automatic debug email from the Aether QR scanner.</p>
</div>
<br>
<div>
Message:<br>
<pre>
${JSON.stringify(message)}
</pre>
</div>
`;
api.send_email({
api_cfg: $ae_api,
from_email: 'noreply+ae_qr_debug@oneskyit.com',
from_name: 'AE QR Debug',
to_email: to_email,
subject: full_subject,
body_html: body_html,
});
}
</script>
<section
class="ae_element qr_scanner border-2 border-slate-500/10 space-y-2 flex flex-col gap-1 justify-center items-center min-w-full max-w-full"
class:not_started={scanning_status == 'not_started'}
class:paused={scanning_status == 'paused'}
class:scanning={scanning_status == 'scanning'}
>
<!-- <header>
<h2>QR Scanner</h2>
</header> -->
<!-- <fieldset class=""> -->
<!-- <legend class="d_none">QR Scanner:</legend> -->
<div
class="ae_container qr_scanning_container"
>
<div
class="ae_options m-1"
>
{#if scanning_status == 'not_started' }
<button on:click={handle_start_qr_scanning} class="btn btn-lg variant-soft-primary btn_start"><span class="fas fa-qrcode mx-1"></span> Start Scanning</button>
<span class="loading-text">
Scanning stopped
</span>
{:else if scanning_status == 'paused' && show_pause_btn}
<button on:click={handle_resume_qr_scanning} class="btn btn-md variant-soft-primary btn_resume"><span class="fas fa-play"></span> Resume</button>
<span>Scanning paused</span>
{:else if scanning_status == 'scanning'}
<button on:click={handle_stop_qr_scanning} class="btn btn-md variant-soft-secondary btn_stop">
<span class="fas fa-crosshairs fa-spin opacity-50 m-1"></span>
<!-- <span class="fas fa-stop-circle m-1"></span> -->
Stop
</button>
{#if show_pause_btn}
<button on:click={handle_pause_qr_scanning} class="btn btn-lg variant-soft-secondary btn_pause"><span class="fas fa-pause-circle"></span> Pause</button>
{/if}
<!-- <span>Scanning for QR code...</span> -->
<!-- <div class="modal-loading"> -->
<!-- <span class="fas fa-crosshairs fa-spin opacity-50"></span> -->
<span class="loading-text">
Scanning for QR code...
</span>
<!-- </div> -->
{/if}
</div>
<div id="qr_scanner_viewfinder" class="qr_scanner_viewfinder grow flex flex-col justify-center items-center" style=""></div> <!-- width: 600px -->
</div>
{#if show_qr_manual_text_entry_option}
<div class="ae_container qr_manual_entry text_entry">
{#if show_qr_manual_entry}
<label for="entered_text" class="">Enter text</label>
<input type="text" name="entered_text" id="entered_text" bind:value="{qr_entered_text}">
<button on:click={handle_qr_manual_entry} class="btn btn-md variant-soft-warning"><span class="fas fa-paper-plane"></span> Submit Text</button>
<div class="search_by_text">
<input type='text' placeholder="Name or Email" label="Name or Email" value={search_query_str} focus={true} on:oninput={handle_oninput_search_query_str} />
</div>
{:else}
<button on:click={() => show_qr_manual_entry=true} class="btn btn-md variant-soft-warning"><span class="fas fa-keyboard"></span> Enter Text</button>
{/if}
</div>
{/if}
{#if show_qr_manual_badge_id_entry_option}
<div class="ae_container qr_manual_entry badge_id_entry">
{#if show_qr_manual_entry}
<form on:submit|preventDefault={() => handle_qr_manual_entry} class="flex">
<!-- <label for="entered_badge_id" class="">Enter badge ID</label>
<input type="text" name="entered_badge_id" id="entered_badge_id" bind:value="{qr_entered_badge_id}"> -->
<input
bind:value="{qr_entered_badge_id}"
type="text"
name="entered_badge_id"
id="entered_badge_id"
required
placeholder="Enter Badge ID"
class="input max-w-52"
/>
<button
type="submit"
on:click={handle_qr_manual_entry}
disabled={disable_submit_badge_id_btn}
class="btn btn-md variant-ghost-primary m-1"
class:btn_default={disable_submit_badge_id_btn}
class:btn_primary={!disable_submit_badge_id_btn}
>
<span class="fas fa-paper-plane mx-1"></span> Submit Badge ID
</button>
</form>
{:else}
<button on:click={() => show_qr_manual_entry=true} class="btn btn-md variant-soft-secondary m-1"><span class="fas fa-keyboard mx-1"></span> Enter Badge ID</button>
{/if}
</div>
{/if}
{#if show_qr_scan_result && qr_scan_result}
<div class="ae_container qr_scan_result">
<span class="label">Raw Result:</span>
<span id="qr_scan_result_value" class="value">{qr_scan_result}</span>
</div>
{/if}
<!-- </fieldset> -->
</section>
<style>
.not_started {
background-color: hsla(0, 100%, 75%, 0.3);
border-color: hsla(0, 100%, 75%, 0.6);
}
.paused {
background-color: hsla(60, 100%, 75%, 0.3);
border-color: hsla(60, 100%, 75%, 0.6);
}
.scanning {
background-color: hsla(120, 100%, 75%, 0.3);
border-color: hsla(120, 100%, 75%, 0.6);
}
.qr_scanner {
/* outline: solid thin pink; */
max-width: 100vw;
/* overflow-x: scroll; */
display: flex;
flex-direction: column;
/* flex-wrap: wrap; */
justify-content: flex-start;
align-items: center; /* center */
align-content: stretch;
}
.ae_element.qr_scanner div.qr_scanner_viewfinder {
/* max-width: 100vw; */
/* contain: content; */
/* contain: contain; */
}
.qr_scanner .qr_scanner_viewfinder {
/* outline: dashed medium blue; */
min-width: 400px;
width: 100%;
/* max-width: 100%; */
max-width: 500px;
/* max-width: 100vw; */
/* outline: solid thin red; */
contain: contain;
overflow-x: scroll;
}
@media (max-width: 767px) {
.qr_scanner .qr_scanner_viewfinder {
/* outline: dashed medium red; */
min-width: 80vw;
/* width: 100%; */
/* max-width: 100%; */
/* max-width: 450px; */
max-width: 100vw;
margin: 0;
padding: 0;
}
}
</style>

View File

@@ -0,0 +1,683 @@
<script lang="ts">
// *** Import Svelte core
import { createEventDispatcher, onDestroy, onMount } from 'svelte';
// import 'html5-qrcode';
import {Html5Qrcode, Html5QrcodeScannerState, Html5QrcodeSupportedFormats} from 'html5-qrcode';
// *** Import Aether core variables and functions
import { api } from '$lib/api';
import { ae_api } from '$lib/ae_stores';
// *** Import Aether core components
// import Element_input from './element_input.svelte';
// import ae from '/element_input.svelte';
// import Input_element from '/element_input.svelte';
// *** Import Aether module variables and functions
// *** Import Aether module components
// *** Export/Exposed variables and functions for component
export let start_qr_scanner: boolean = true;
export let show_pause_btn: boolean = false; // pause and resume buttons
export let show_qr_manual_text_entry_option: boolean = false;
export let show_qr_manual_badge_id_entry_option: boolean = false;
export let show_qr_scan_result: boolean = true;
export let qr_fps = 10;
export let qr_viewfinder_width = 275; // 275 seems good... Need to not let the this be larger than the container which changes based on the width of the screen/window.
export let qr_facing_mode = 'environment'; // environment, user, { exact: 'environment'}, { exact: 'user'}
// *** Set initial variables
let scanning_status: string = 'not_started';
let qr_scan_result: null|string = null;
let qr_found_text: null|string = null;
let qr_entered_text: null|string = null;
let qr_entered_badge_id: null|string = null;
let show_qr_manual_entry: null|boolean = null;
let disable_submit_badge_id_btn: boolean = true;
let user_media_status = 'not_requested';
let debug_comment: string = 'Debugging QR Scanner';
let debug_info: any;
// let max_results: number = 50;
const dispatch = createEventDispatcher();
let html5_qr_code: any|null|string = null;
// let html5_qr_code = new Html5Qrcode(
// 'qr_scanner_viewfinder', { formatsToSupport: [ Html5QrcodeSupportedFormats.QR_CODE ] }
// );
// let qr_scan_cfg = { fps: 10, qrbox: 400 }; // default was 250 and using 300 when 600px
// let qr_scan_cfg = { fps: qr_fps, qrbox: qr_viewfinder_width }; // 275 seems good... Need to not let the this be larger than the container which changes based on the width of the screen/window.
let qr_scan_cfg = {};
// let mounted = false;
onMount(() => {
console.log('** Element Mounted: ** QR Scanner');
console.log('** Element Mounted: ** QR Scanner - getUserMedia');
var constraints = {
video: false,
audio: false
}
navigator.mediaDevices.getUserMedia(constraints)
.then(get_user_media_success, get_user_media_error);
// navigator.mediaDevices.getUserMedia(constraints)
// .then(get_user_media_success, get_user_media_error)
// .catch(function(err) {
// //log to console first
// console.log(err); /* handle the error */
// if (err.name == "NotFoundError" || err.name == "DevicesNotFoundError") {
// //required track is missing
// } else if (err.name == "NotReadableError" || err.name == "TrackStartError") {
// //webcam or mic are already in use
// } else if (err.name == "OverconstrainedError" || err.name == "ConstraintNotSatisfiedError") {
// //constraints can not be satisfied by avb. devices
// } else if (err.name == "NotAllowedError" || err.name == "PermissionDeniedError") {
// //permission denied in browser
// } else if (err.name == "TypeError" || err.name == "TypeError") {
// //empty constraints object
// } else {
// //other errors
// }
// });
// navigator.mediaDevices.getUserMedia({video: true})
// .then(get_user_media_success, get_user_media_error);
// console.log('** Element Mounted: ** QR Scanner - setTimeout 750ms then getUserMedia');
// Wait 250ms for everything to fully load
// setTimeout(() => {
// console.log('** Element Mounted: ** QR Scanner - inside setTimeout 750ms');
// navigator.mediaDevices.getUserMedia({video: true})
// .then(get_user_media_success, get_user_media_error);
// }, 750);
// console.log('** Element Mounted: ** QR Scanner - setTimeout end 750ms');
// NOTE: This can only be done after the page has fully loaded.
// if (start_qr_scanner) {
// handle_start_qr_scanning();
// }
});
onDestroy(async () => {
console.log('** Element Destroyed: ** QR Scanner');
qr_scan_result = null;
qr_found_text = null;
await handle_stop_qr_scanning();
});
var get_user_media_success = function(error: any) {
console.log('Camera access allowed');
user_media_status = 'allowed';
debug_comment = 'Camera Access Allowed';
debug_info = JSON.stringify(error);
// if (html5_qr_code) {
// console.log('html5_qr_code object found. Clearing and creating new Html5Qrcode...');
// debug_info = 'html5_qr_code object found. Clearing and creating new Html5Qrcode...';
// html5_qr_code.clear();
// // document.getElementById('qr_scanner_viewfinder').classList.remove('d_none');
// } else {
// console.log('html5_qr_code not found. Creating new Html5Qrcode...');
// debug_info = 'html5_qr_code not found. Creating new Html5Qrcode...';
// }
html5_qr_code = new Html5Qrcode(
'qr_scanner_viewfinder', { formatsToSupport: [ Html5QrcodeSupportedFormats.QR_CODE ] }
);
debug_comment = 'Html5Qrcode created';
debug_info = 'new Html5Qrcode for element id=qr_scanner_viewfinder QR_CODE';
if (start_qr_scanner) {
// console.log('** Element Mounted: ** QR Scanner - getUserMedia in setTimeout');
setTimeout(() => {
console.log('** Element Mounted: ** QR Scanner - setTimeout');
console.log('Ready to start QR scanning!');
debug_info = 'Ready to start QR scanning!';
handle_start_qr_scanning();
}, 2500);
// console.log('** Element Mounted: ** QR Scanner - setTimeout end');
}
// let subject = 'Camera Access Allowed';
// let message = error;
// send_init_confirm_email(subject, message);
console.log('Dispatching qr_camera');
debug_info = 'Dispatching qr_camera';
dispatch('qr_camera', {
status: 'allowed',
});
// NOTE: This can only be done after the page has fully loaded.
// if (start_qr_scanner) {
// handle_start_qr_scanning();
// }
};
var get_user_media_error = function(error: any) {
if (error.name == 'NotAllowedError') {
console.log('Camera access not allowed!');
user_media_status = 'denied';
debug_comment = 'Camera Access Denied';
debug_info = JSON.stringify(error);
// alert('Error trying to start camera');
// alert(error);
let subject = 'Camera Access Denied';
let message = error;
send_init_confirm_email(subject, message);
dispatch('qr_camera', {
status: 'denied',
});
}
};
// $: if (start_qr_scanner && user_media_status == 'allowed' && (scanning_status == 'not_started' || scanning_status == 'paused')) {
// console.log('START QR SCANNING');
// handle_start_qr_scanning();
// } else {
// // console.log('STOP QR SCANNING');
// // handle_stop_qr_scanning();
// }
// $: if (mounted && start_qr_scanner) {
// console.log('START QR SCANNING');
// handle_start_qr_scanning();
// } else if (mounted && !start_qr_scanner) {
// console.log('STOP QR SCANNING');
// handle_stop_qr_scanning();
// }
async function handle_start_qr_scanning() {
console.log('*** handle_start_qr_scanning() ***');
if (user_media_status == 'denied') {
console.log('Camera access not allowed!');
return;
} else if (user_media_status == 'not_requested') {
console.log('Camera access not requested yet!');
return;
} else if (user_media_status == 'allowed') {
console.log('Camera access allowed!');
debug_info = 'Camera access allowed!';
} else {
console.log('Camera access status unknown! This should not happen?');
debug_info = 'Camera access status unknown! This should not happen?';
return;
}
qr_scan_result = null;
qr_found_text = null;
debug_comment = 'Starting QR Scanning...';
// if (html5_qr_code) {
// console.log('html5_qr_code object found. Clearing and creating new Html5Qrcode...');
// debug_info = 'html5_qr_code object found. Clearing and creating new Html5Qrcode...';
// html5_qr_code.clear();
// // document.getElementById('qr_scanner_viewfinder').classList.remove('d_none');
// html5_qr_code = new Html5Qrcode(
// 'qr_scanner_viewfinder', { formatsToSupport: [ Html5QrcodeSupportedFormats.QR_CODE ] }
// );
// } else {
// console.log('html5_qr_code not found. Creating new Html5Qrcode...');
// debug_info = 'html5_qr_code not found. Creating new Html5Qrcode...';
// html5_qr_code = new Html5Qrcode(
// 'qr_scanner_viewfinder', { formatsToSupport: [ Html5QrcodeSupportedFormats.QR_CODE ] }
// );
// }
debug_info = 'Check the state and start if not started...';
let current_state = await html5_qr_code.getState()
if (current_state == Html5QrcodeScannerState.NOT_STARTED) {
// console.log('Scanner is not started');
debug_info = 'Waiting... Scanner is not started';
setTimeout(() => {
debug_info = 'Waited long enough! Starting for real!';
html5_qr_code.start({ facingMode: qr_facing_mode }, qr_scan_cfg, handle_qr_scan_success, handle_qr_scan_error)
.then((ignore: any) => {
console.log('Scanning has started');
scanning_status = 'scanning';
debug_info = 'Scanning has started';
// let subject = 'QR Scanning Started';
// let message = ignore;
// send_init_confirm_email(subject, message);
return true;
}).catch((err) => {
console.log('There was an error while trying to start the QR scanner');
scanning_status = 'start_error';
debug_comment = 'Error starting scanner after getState() NOT_STARTED';
debug_info = 'Error starting scanner: ' + JSON.stringify(err);
// let subject = 'QR Scanning Start Error';
// let message = err;
// send_init_confirm_email(subject, message);
// Error getting userMedia, error = NotReadableError: Could not start video source
return false;
});
}, 750);
debug_info = 'Waiting...?';
} else {
console.log('Scanner is already started');
debug_info = 'Scanner is already started';
return;
}
}
function handle_pause_qr_scanning() {
if (html5_qr_code && html5_qr_code.getState() != Html5QrcodeScannerState.SCANNING) {
console.log('Scanner is not scanning!');
return;
}
html5_qr_code.pause();
scanning_status = 'paused';
}
function handle_resume_qr_scanning() {
if (html5_qr_code && html5_qr_code.getState() != Html5QrcodeScannerState.PAUSED) {
console.log('Scanner is not paused!');
return;
}
document.getElementById('qr_scanner_viewfinder').classList.remove('d_none');
html5_qr_code.resume();
scanning_status = 'scanning';
}
async function handle_stop_qr_scanning() {
start_qr_scanner = false;
if (!html5_qr_code) {
console.log('html5_qr_code object found. Nothing to stop?');
return false;
}
let state = html5_qr_code.getState();
console.log('html5_qr_code state:', state);
if (state == Html5QrcodeScannerState.NOT_STARTED) {
console.log('Scanner is not started');
return;
}
if (state == Html5QrcodeScannerState.PAUSED || state == Html5QrcodeScannerState.SCANNING) {
console.log('Scanner is not started');
await html5_qr_code.stop()
scanning_status = 'not_started';
return;
}
await html5_qr_code.clear();
return true;
// html5_qr_code.pause();
// return html5_qr_code.stop()
// .then((ignore) => {
// console.log('Scanning has stopped');
// // document.getElementById('qr_scanner_viewfinder').classList.add('d_none');
// scanning_status = 'not_started';
// }).then((ignore) => {
// // html5_qr_code = null;
// // html5_qr_code.clear();
// }).catch((err) => {
// console.log('There was an error while trying to stop the scanning');
// return false;
// });
// html5_qr_code = null;
}
// Callback function for QrcodeSuccessCallback (decodedText: string, result: Html5QrcodeResult)
function handle_qr_scan_success(decoded_text, decoded_result) {
console.log('*** handle_qr_scan_success() ***');
console.log(`QR scanned = ${decoded_text}`, decoded_result);
qr_scan_result = decoded_text; // NOTE: decoded_result is not currently used by html5-qrcode
qr_found_text = decoded_text;
dispatch('qr_scan_result', {
result: qr_scan_result, // This text will need to be parsed to get more info.
text: qr_found_text, // This text will need to be parsed to get more info.
entry_method: 'QR',
});
// handle_pause_qr_scanning();
handle_stop_qr_scanning();
}
// Callback function for QrcodeErrorCallback (errorMessage: string, error: Html5QrcodeError)
// NOTE: Most of the time this is normal and not an actual error. It just did not find something to scan.
function handle_qr_scan_error(qr_error_message, qr_code_error) {
// console.log('*** handle_qr_scan_error() ***');
if (qr_code_error.type) {
console.log(`Error scanning code = ${qr_error_message}`, qr_code_error);
return;
}
}
$: if ( qr_entered_badge_id && qr_entered_badge_id.length >= 11 && qr_entered_badge_id && qr_entered_badge_id.length <= 14) {
disable_submit_badge_id_btn = false;
} else {
disable_submit_badge_id_btn = true;
}
function handle_qr_manual_entry() {
console.log('*** handle_qr_manual_entry() ***');
if (qr_entered_text) {
console.log(`QR entered text = ${qr_entered_text}`);
} else if (qr_entered_badge_id) {
console.log(`QR entered badge ID = ${qr_entered_badge_id}`);
qr_entered_text = `OBJ:ot:event_badge,oi:${qr_entered_badge_id}`;
console.log(`Parse to proper QR badge ID = ${qr_entered_text}`);
}
// html5_qr_code.stop().then((ignore) => {
// console.log('Scanning has stopped');
// document.getElementById('qr_scanner_viewfinder').classList.add('d_none');
// }).catch((err) => {
// console.log('There was an error while trying to stop the scanning');
// });
qr_scan_result = qr_entered_text;
dispatch('qr_scan_result', {
result: qr_scan_result,
entry_method: 'manual',
});
qr_scan_result = null;
qr_entered_text = null;
}
function send_init_confirm_email(subject, message) {
console.log(`*** send_init_confirm_email() *** ${subject}`);
let to_email = 'scott.idem+skdev@oneskyit.com';
// let origin_url = encodeURI(`${data.url.origin}`);
let full_subject = `${subject} Aether QR Scanner Debugging`;
let body_html = `
<div>Scott,
<p>This is an automatic debug email from the Aether QR scanner.</p>
</div>
<br>
<div>
Message:<br>
<pre>
${JSON.stringify(message)}
</pre>
</div>
`;
api.send_email({
api_cfg: $ae_api,
from_email: 'noreply+ae_qr_debug@oneskyit.com',
from_name: 'AE QR Debug',
to_email: to_email,
subject: full_subject,
body_html: body_html,
});
}
</script>
<section
class="ae_element qr_scanner border-2 border-slate-500/10 space-y-2 flex flex-col gap-1 justify-center items-center min-w-full max-w-full"
class:not_started={scanning_status == 'not_started'}
class:paused={scanning_status == 'paused'}
class:scanning={scanning_status == 'scanning'}
>
<!-- <header>
<h2>QR Scanner</h2>
</header> -->
<!-- <fieldset class=""> -->
<!-- <legend class="d_none">QR Scanner:</legend> -->
<div
class="ae_container qr_scanning_container"
>
<div
class="ae_options m-1"
>
{#if scanning_status == 'not_started' }
<button on:click={handle_start_qr_scanning} class="btn btn-lg variant-soft-primary btn_start"><span class="fas fa-qrcode mx-1"></span> Start Scanning</button>
<span class="loading-text">
Scanning stopped
</span>
{:else if scanning_status == 'paused' && show_pause_btn}
<button on:click={handle_resume_qr_scanning} class="btn btn-md variant-soft-primary btn_resume"><span class="fas fa-play"></span> Resume</button>
<span>Scanning paused</span>
{:else if scanning_status == 'scanning'}
<button on:click={handle_stop_qr_scanning} class="btn btn-md variant-soft-secondary btn_stop">
<span class="fas fa-crosshairs fa-spin opacity-50 m-1"></span>
<!-- <span class="fas fa-stop-circle m-1"></span> -->
Stop
</button>
{#if show_pause_btn}
<button on:click={handle_pause_qr_scanning} class="btn btn-lg variant-soft-secondary btn_pause"><span class="fas fa-pause-circle"></span> Pause</button>
{/if}
<!-- <span>Scanning for QR code...</span> -->
<!-- <div class="modal-loading"> -->
<!-- <span class="fas fa-crosshairs fa-spin opacity-50"></span> -->
<span class="loading-text">
Scanning for QR code...
</span>
<!-- </div> -->
{/if}
</div>
<div id="qr_scanner_viewfinder" class="qr_scanner_viewfinder grow flex flex-col justify-center items-center" style=""></div> <!-- width: 600px -->
</div>
{#if show_qr_manual_text_entry_option}
<div class="ae_container qr_manual_entry text_entry">
{#if show_qr_manual_entry}
<label for="entered_text" class="">Enter text</label>
<input type="text" name="entered_text" id="entered_text" bind:value="{qr_entered_text}">
<button on:click={handle_qr_manual_entry} class="btn btn-md variant-soft-warning"><span class="fas fa-paper-plane"></span> Submit Text</button>
<div class="search_by_text">
<input type='text' placeholder="Name or Email" label="Name or Email" value={search_query_str} focus={true} on:oninput={handle_oninput_search_query_str} />
</div>
{:else}
<button on:click={() => show_qr_manual_entry=true} class="btn btn-md variant-soft-warning"><span class="fas fa-keyboard"></span> Enter Text</button>
{/if}
</div>
{/if}
{#if show_qr_manual_badge_id_entry_option}
<div class="ae_container qr_manual_entry badge_id_entry">
{#if show_qr_manual_entry}
<form on:submit|preventDefault={() => handle_qr_manual_entry} class="flex">
<!-- <label for="entered_badge_id" class="">Enter badge ID</label>
<input type="text" name="entered_badge_id" id="entered_badge_id" bind:value="{qr_entered_badge_id}"> -->
<input
bind:value="{qr_entered_badge_id}"
type="text"
name="entered_badge_id"
id="entered_badge_id"
required
placeholder="Enter Badge ID"
class="input max-w-52"
/>
<button
type="submit"
on:click={handle_qr_manual_entry}
disabled={disable_submit_badge_id_btn}
class="btn btn-md variant-ghost-primary m-1"
class:btn_default={disable_submit_badge_id_btn}
class:btn_primary={!disable_submit_badge_id_btn}
>
<span class="fas fa-paper-plane mx-1"></span> Submit Badge ID
</button>
</form>
{:else}
<button on:click={() => show_qr_manual_entry=true} class="btn btn-md variant-soft-secondary m-1"><span class="fas fa-keyboard mx-1"></span> Enter Badge ID</button>
{/if}
</div>
{/if}
{#if show_qr_scan_result && qr_scan_result}
<div class="ae_container qr_scan_result">
<span class="label">Raw Result:</span>
<span id="qr_scan_result_value" class="value">{qr_scan_result}</span>
</div>
{/if}
{debug_comment ?? 'Debugging QR Scanner'}
{#if debug_info}
<div class="ae_container debug_info">
<span class="label">Debug Info:</span>
<span class="value">{debug_info}</span>
</div>
{/if}
<!-- </fieldset> -->
</section>
<style>
.not_started {
background-color: hsla(0, 100%, 75%, 0.3);
border-color: hsla(0, 100%, 75%, 0.6);
}
.paused {
background-color: hsla(60, 100%, 75%, 0.3);
border-color: hsla(60, 100%, 75%, 0.6);
}
.scanning {
background-color: hsla(120, 100%, 75%, 0.3);
border-color: hsla(120, 100%, 75%, 0.6);
}
.qr_scanner {
/* outline: solid thin pink; */
max-width: 100vw;
/* overflow-x: scroll; */
display: flex;
flex-direction: column;
/* flex-wrap: wrap; */
justify-content: flex-start;
align-items: center; /* center */
align-content: stretch;
}
.ae_element.qr_scanner div.qr_scanner_viewfinder {
/* max-width: 100vw; */
/* contain: content; */
/* contain: contain; */
}
.qr_scanner .qr_scanner_viewfinder {
/* outline: dashed medium blue; */
min-width: 400px;
width: 100%;
/* max-width: 100%; */
max-width: 500px;
/* max-width: 100vw; */
/* outline: solid thin red; */
contain: contain;
overflow-x: scroll;
}
@media (max-width: 767px) {
.qr_scanner .qr_scanner_viewfinder {
/* outline: dashed medium red; */
min-width: 80vw;
/* width: 100%; */
/* max-width: 100%; */
/* max-width: 450px; */
max-width: 100vw;
margin: 0;
padding: 0;
}
}
</style>

View File

@@ -0,0 +1,641 @@
<script lang="ts">
// *** Import Svelte core
import { createEventDispatcher, onDestroy, onMount } from 'svelte';
// import 'html5-qrcode';
import {Html5Qrcode, Html5QrcodeScannerState, Html5QrcodeSupportedFormats} from 'html5-qrcode';
// *** Import Aether core variables and functions
import { api } from '$lib/api';
import { ae_api } from '$lib/ae_stores';
// *** Import Aether core components
// import Element_input from './element_input.svelte';
// import ae from '/element_input.svelte';
// import Input_element from '/element_input.svelte';
// *** Import Aether module variables and functions
// *** Import Aether module components
// *** Export/Exposed variables and functions for component
export let start_qr_scanner: boolean = true;
export let show_pause_btn: boolean = false; // pause and resume buttons
export let show_qr_manual_text_entry_option: boolean = false;
export let show_qr_manual_badge_id_entry_option: boolean = false;
export let show_qr_scan_result: boolean = true;
export let qr_fps = 10;
export let qr_viewfinder_width = 275; // 275 seems good... Need to not let the this be larger than the container which changes based on the width of the screen/window.
export let qr_facing_mode = 'environment'; // environment, user, { exact: 'environment'}, { exact: 'user'}
// *** Set initial variables
let scanning_status: string = 'not_started';
let qr_scan_result: null|string = null;
let qr_found_text: null|string = null;
let qr_entered_text: null|string = null;
let qr_entered_badge_id: null|string = null;
let show_qr_manual_entry: null|boolean = null;
let disable_submit_badge_id_btn: boolean = true;
let user_media_status = 'not_requested';
let debug_comment: string = 'Debugging QR Scanner';
let debug_info: any;
// let max_results: number = 50;
const dispatch = createEventDispatcher();
let html5_qr_code: any|null|string = null;
// let html5_qr_code = new Html5Qrcode(
// 'qr_scanner_viewfinder', { formatsToSupport: [ Html5QrcodeSupportedFormats.QR_CODE ] }
// );
// let qr_scan_cfg = { fps: 10, qrbox: 400 }; // default was 250 and using 300 when 600px
let qr_scan_cfg = { fps: qr_fps, qrbox: qr_viewfinder_width }; // 275 seems good... Need to not let the this be larger than the container which changes based on the width of the screen/window.
// let mounted = false;
onMount(() => {
console.log('** Element Mounted: ** QR Scanner');
// Wait 250ms for everything to fully load
// setTimeout(() => {
// console.log('** Element Mounted: ** QR Scanner - setTimeout');
// NOTE: We only want to trigger the scanning to start after the page has fully loaded.
navigator.mediaDevices.getUserMedia({video: true})
.then(successCallback, errorCallback);
console.log('** Element Mounted: ** QR Scanner - getUserMedia in setTimeout');
// mounted = true;
// }, 750);
// console.log('** Element Mounted: ** QR Scanner - setTimeout end');
// NOTE: This can only be done after the page has fully loaded.
// if (start_qr_scanner) {
// handle_start_qr_scanning();
// }
});
onDestroy(async () => {
console.log('** Element Destroyed: ** QR Scanner');
qr_scan_result = null;
qr_found_text = null;
await handle_stop_qr_scanning();
});
var successCallback = function(error: any) {
console.log('Camera access allowed');
user_media_status = 'allowed';
debug_comment = 'Camera Access Allowed';
debug_info = JSON.stringify(error);
if (html5_qr_code) {
console.log('html5_qr_code object found. Clearing and creating new Html5Qrcode...');
debug_info = 'html5_qr_code object found. Clearing and creating new Html5Qrcode...';
html5_qr_code.clear();
// document.getElementById('qr_scanner_viewfinder').classList.remove('d_none');
} else {
console.log('html5_qr_code not found. Creating new Html5Qrcode...');
debug_info = 'html5_qr_code not found. Creating new Html5Qrcode...';
}
html5_qr_code = new Html5Qrcode(
'qr_scanner_viewfinder', { formatsToSupport: [ Html5QrcodeSupportedFormats.QR_CODE ] }
);
debug_info = 'new Html5Qrcode for element id=qr_scanner_viewfinder';
if (start_qr_scanner) {
console.log('Ready to start QR scanning!');
debug_info = 'Ready to start QR scanning!';
handle_start_qr_scanning();
}
// let subject = 'Camera Access Allowed';
// let message = error;
// send_init_confirm_email(subject, message);
console.log('Dispatching qr_camera');
debug_info = 'Dispatching qr_camera';
dispatch('qr_camera', {
status: 'allowed',
});
// NOTE: This can only be done after the page has fully loaded.
// if (start_qr_scanner) {
// handle_start_qr_scanning();
// }
};
var errorCallback = function(error: any) {
if (error.name == 'NotAllowedError') {
console.log('Camera access not allowed!');
user_media_status = 'denied';
debug_comment = 'Camera Access Denied';
debug_info = JSON.stringify(error);
// alert('Error trying to start camera');
// alert(error);
let subject = 'Camera Access Denied';
let message = error;
send_init_confirm_email(subject, message);
dispatch('qr_camera', {
status: 'denied',
});
}
};
// $: if (start_qr_scanner && user_media_status == 'allowed' && (scanning_status == 'not_started' || scanning_status == 'paused')) {
// console.log('START QR SCANNING');
// handle_start_qr_scanning();
// } else {
// // console.log('STOP QR SCANNING');
// // handle_stop_qr_scanning();
// }
// $: if (mounted && start_qr_scanner) {
// console.log('START QR SCANNING');
// handle_start_qr_scanning();
// } else if (mounted && !start_qr_scanner) {
// console.log('STOP QR SCANNING');
// handle_stop_qr_scanning();
// }
async function handle_start_qr_scanning() {
console.log('*** handle_start_qr_scanning() ***');
if (user_media_status == 'denied') {
console.log('Camera access not allowed!');
return;
} else if (user_media_status == 'not_requested') {
console.log('Camera access not requested yet!');
return;
} else if (user_media_status == 'allowed') {
console.log('Camera access allowed!');
debug_info = 'Camera access allowed!';
} else {
console.log('Camera access status unknown! This should not happen?');
debug_info = 'Camera access status unknown! This should not happen?';
return;
}
qr_scan_result = null;
qr_found_text = null;
debug_comment = 'Starting QR Scanning...';
// if (html5_qr_code) {
// console.log('html5_qr_code object found. Clearing and creating new Html5Qrcode...');
// debug_info = 'html5_qr_code object found. Clearing and creating new Html5Qrcode...';
// html5_qr_code.clear();
// // document.getElementById('qr_scanner_viewfinder').classList.remove('d_none');
// html5_qr_code = new Html5Qrcode(
// 'qr_scanner_viewfinder', { formatsToSupport: [ Html5QrcodeSupportedFormats.QR_CODE ] }
// );
// } else {
// console.log('html5_qr_code not found. Creating new Html5Qrcode...');
// debug_info = 'html5_qr_code not found. Creating new Html5Qrcode...';
// html5_qr_code = new Html5Qrcode(
// 'qr_scanner_viewfinder', { formatsToSupport: [ Html5QrcodeSupportedFormats.QR_CODE ] }
// );
// }
debug_info = 'Check the state and start if not started...';
let current_state = await html5_qr_code.getState()
if (current_state == Html5QrcodeScannerState.NOT_STARTED) {
// console.log('Scanner is not started');
return await html5_qr_code.start({ facingMode: qr_facing_mode }, qr_scan_cfg, handle_qr_scan_success, handle_qr_scan_error)
.then((ignore: any) => {
console.log('Scanning has started');
scanning_status = 'scanning';
debug_info = 'Scanning has started';
// let subject = 'QR Scanning Started';
// let message = ignore;
// send_init_confirm_email(subject, message);
return true;
}).catch((err) => {
console.log('There was an error while trying to start the QR scanner');
scanning_status = 'start_error';
debug_info = 'Error starting scanner: ' + JSON.stringify(err);
// let subject = 'QR Scanning Start Error';
// let message = err;
// send_init_confirm_email(subject, message);
// Error getting userMedia, error = NotReadableError: Could not start video source
return false;
});
} else {
console.log('Scanner is already started');
debug_info = 'Scanner is already started';
return;
}
}
function handle_pause_qr_scanning() {
if (html5_qr_code && html5_qr_code.getState() != Html5QrcodeScannerState.SCANNING) {
console.log('Scanner is not scanning!');
return;
}
html5_qr_code.pause();
scanning_status = 'paused';
}
function handle_resume_qr_scanning() {
if (html5_qr_code && html5_qr_code.getState() != Html5QrcodeScannerState.PAUSED) {
console.log('Scanner is not paused!');
return;
}
document.getElementById('qr_scanner_viewfinder').classList.remove('d_none');
html5_qr_code.resume();
scanning_status = 'scanning';
}
async function handle_stop_qr_scanning() {
start_qr_scanner = false;
if (!html5_qr_code) {
console.log('html5_qr_code object found. Nothing to stop?');
return false;
}
let state = html5_qr_code.getState();
console.log('html5_qr_code state:', state);
if (state == Html5QrcodeScannerState.NOT_STARTED) {
console.log('Scanner is not started');
return;
}
if (state == Html5QrcodeScannerState.PAUSED || state == Html5QrcodeScannerState.SCANNING) {
console.log('Scanner is not started');
await html5_qr_code.stop()
scanning_status = 'not_started';
return;
}
await html5_qr_code.clear();
return true;
// html5_qr_code.pause();
// return html5_qr_code.stop()
// .then((ignore) => {
// console.log('Scanning has stopped');
// // document.getElementById('qr_scanner_viewfinder').classList.add('d_none');
// scanning_status = 'not_started';
// }).then((ignore) => {
// // html5_qr_code = null;
// // html5_qr_code.clear();
// }).catch((err) => {
// console.log('There was an error while trying to stop the scanning');
// return false;
// });
// html5_qr_code = null;
}
// Callback function for QrcodeSuccessCallback (decodedText: string, result: Html5QrcodeResult)
function handle_qr_scan_success(decoded_text, decoded_result) {
console.log('*** handle_qr_scan_success() ***');
console.log(`QR scanned = ${decoded_text}`, decoded_result);
qr_scan_result = decoded_text; // NOTE: decoded_result is not currently used by html5-qrcode
qr_found_text = decoded_text;
dispatch('qr_scan_result', {
result: qr_scan_result, // This text will need to be parsed to get more info.
text: qr_found_text, // This text will need to be parsed to get more info.
entry_method: 'QR',
});
// handle_pause_qr_scanning();
handle_stop_qr_scanning();
}
// Callback function for QrcodeErrorCallback (errorMessage: string, error: Html5QrcodeError)
// NOTE: Most of the time this is normal and not an actual error. It just did not find something to scan.
function handle_qr_scan_error(qr_error_message, qr_code_error) {
// console.log('*** handle_qr_scan_error() ***');
if (qr_code_error.type) {
console.log(`Error scanning code = ${qr_error_message}`, qr_code_error);
return;
}
}
$: if ( qr_entered_badge_id && qr_entered_badge_id.length >= 11 && qr_entered_badge_id && qr_entered_badge_id.length <= 14) {
disable_submit_badge_id_btn = false;
} else {
disable_submit_badge_id_btn = true;
}
function handle_qr_manual_entry() {
console.log('*** handle_qr_manual_entry() ***');
if (qr_entered_text) {
console.log(`QR entered text = ${qr_entered_text}`);
} else if (qr_entered_badge_id) {
console.log(`QR entered badge ID = ${qr_entered_badge_id}`);
qr_entered_text = `OBJ:ot:event_badge,oi:${qr_entered_badge_id}`;
console.log(`Parse to proper QR badge ID = ${qr_entered_text}`);
}
// html5_qr_code.stop().then((ignore) => {
// console.log('Scanning has stopped');
// document.getElementById('qr_scanner_viewfinder').classList.add('d_none');
// }).catch((err) => {
// console.log('There was an error while trying to stop the scanning');
// });
qr_scan_result = qr_entered_text;
dispatch('qr_scan_result', {
result: qr_scan_result,
entry_method: 'manual',
});
qr_scan_result = null;
qr_entered_text = null;
}
function send_init_confirm_email(subject, message) {
console.log(`*** send_init_confirm_email() *** ${subject}`);
let to_email = 'scott.idem+skdev@oneskyit.com';
// let origin_url = encodeURI(`${data.url.origin}`);
let full_subject = `${subject} Aether QR Scanner Debugging`;
let body_html = `
<div>Scott,
<p>This is an automatic debug email from the Aether QR scanner.</p>
</div>
<br>
<div>
Message:<br>
<pre>
${JSON.stringify(message)}
</pre>
</div>
`;
api.send_email({
api_cfg: $ae_api,
from_email: 'noreply+ae_qr_debug@oneskyit.com',
from_name: 'AE QR Debug',
to_email: to_email,
subject: full_subject,
body_html: body_html,
});
}
</script>
<section
class="ae_element qr_scanner border-2 border-slate-500/10 space-y-2 flex flex-col gap-1 justify-center items-center min-w-full max-w-full"
class:not_started={scanning_status == 'not_started'}
class:paused={scanning_status == 'paused'}
class:scanning={scanning_status == 'scanning'}
>
<!-- <header>
<h2>QR Scanner</h2>
</header> -->
<!-- <fieldset class=""> -->
<!-- <legend class="d_none">QR Scanner:</legend> -->
<div
class="ae_container qr_scanning_container"
>
<div
class="ae_options flex flex-row justify-center items-center gap-1 m-1"
>
{#if scanning_status == 'not_started' }
<button on:click={handle_start_qr_scanning} class="btn btn-lg variant-soft-primary btn_start"><span class="fas fa-qrcode mx-1"></span> Start Scanning</button>
<span class="loading-text">
Scanning stopped
</span>
{:else if scanning_status == 'paused' && show_pause_btn}
<button on:click={handle_resume_qr_scanning} class="btn btn-md variant-soft-primary btn_resume"><span class="fas fa-play"></span> Resume</button>
<span>Scanning paused</span>
{:else if scanning_status == 'scanning'}
<button on:click={handle_stop_qr_scanning} class="btn btn-md variant-soft-secondary btn_stop">
<span class="fas fa-crosshairs fa-spin opacity-50 m-1"></span>
<!-- <span class="fas fa-stop-circle m-1"></span> -->
Stop
</button>
{#if show_pause_btn}
<button on:click={handle_pause_qr_scanning} class="btn btn-lg variant-soft-secondary btn_pause"><span class="fas fa-pause-circle"></span> Pause</button>
{/if}
<!-- <span>Scanning for QR code...</span> -->
<!-- <div class="modal-loading"> -->
<!-- <span class="fas fa-crosshairs fa-spin opacity-50"></span> -->
<span class="loading-text">
Scanning for QR code...
</span>
<!-- </div> -->
{/if}
</div>
<div id="qr_scanner_viewfinder" class="qr_scanner_viewfinder grow flex flex-col justify-center items-center" style=""></div> <!-- width: 600px -->
</div>
{#if show_qr_manual_text_entry_option}
<div class="ae_container qr_manual_entry text_entry">
{#if show_qr_manual_entry}
<label for="entered_text" class="">Enter text</label>
<input type="text" name="entered_text" id="entered_text" bind:value="{qr_entered_text}">
<button on:click={handle_qr_manual_entry} class="btn btn-md variant-soft-warning"><span class="fas fa-paper-plane"></span> Submit Text</button>
<div class="search_by_text">
<input type='text' placeholder="Name or Email" label="Name or Email" value={search_query_str} focus={true} on:oninput={handle_oninput_search_query_str} />
</div>
{:else}
<button on:click={() => show_qr_manual_entry=true} class="btn btn-md variant-soft-warning"><span class="fas fa-keyboard"></span> Enter Text</button>
{/if}
</div>
{/if}
{#if show_qr_manual_badge_id_entry_option}
<div class="ae_container qr_manual_entry badge_id_entry">
{#if show_qr_manual_entry}
<form on:submit|preventDefault={() => handle_qr_manual_entry} class="flex">
<!-- <label for="entered_badge_id" class="">Enter badge ID</label>
<input type="text" name="entered_badge_id" id="entered_badge_id" bind:value="{qr_entered_badge_id}"> -->
<input
bind:value="{qr_entered_badge_id}"
type="text"
name="entered_badge_id"
id="entered_badge_id"
required
placeholder="Enter Badge ID"
class="input max-w-52"
/>
<button
type="submit"
on:click={handle_qr_manual_entry}
disabled={disable_submit_badge_id_btn}
class="btn btn-md variant-ghost-primary m-1"
class:btn_default={disable_submit_badge_id_btn}
class:btn_primary={!disable_submit_badge_id_btn}
>
<span class="fas fa-paper-plane mx-1"></span> Submit Badge ID
</button>
</form>
{:else}
<button on:click={() =>
{
handle_stop_qr_scanning();
show_qr_manual_entry=true;
}}
class="btn btn-md variant-soft-secondary m-1"
>
<span class="fas fa-keyboard mx-1"></span> Enter Badge ID
</button>
{/if}
</div>
{/if}
{#if show_qr_scan_result && qr_scan_result}
<div class="ae_container qr_scan_result">
<span class="label">Raw Result:</span>
<span id="qr_scan_result_value" class="value">{qr_scan_result}</span>
</div>
{/if}
<!-- {debug_comment ?? 'Debugging QR Scanner'}
{#if debug_info}
<div class="ae_container debug_info">
<span class="label">Debug Info:</span>
<span class="value">{debug_info}</span>
</div>
{/if} -->
<!-- </fieldset> -->
</section>
<style>
.not_started {
background-color: hsla(0, 100%, 75%, 0.3);
border-color: hsla(0, 100%, 75%, 0.6);
}
.paused {
background-color: hsla(60, 100%, 75%, 0.3);
border-color: hsla(60, 100%, 75%, 0.6);
}
.scanning {
background-color: hsla(120, 100%, 75%, 0.3);
border-color: hsla(120, 100%, 75%, 0.6);
}
.qr_scanner {
/* outline: solid thin pink; */
max-width: 100vw;
/* overflow-x: scroll; */
display: flex;
flex-direction: column;
/* flex-wrap: wrap; */
justify-content: flex-start;
align-items: center; /* center */
align-content: stretch;
}
.ae_element.qr_scanner div.qr_scanner_viewfinder {
/* max-width: 100vw; */
/* contain: content; */
/* contain: contain; */
}
.qr_scanner .qr_scanner_viewfinder {
/* outline: dashed medium blue; */
min-width: 400px;
width: 100%;
/* max-width: 100%; */
max-width: 500px;
/* max-width: 100vw; */
/* outline: solid thin red; */
contain: contain;
overflow-x: scroll;
}
@media (max-width: 767px) {
.qr_scanner .qr_scanner_viewfinder {
/* outline: dashed medium red; */
min-width: 80vw;
/* width: 100%; */
/* max-width: 100%; */
/* max-width: 450px; */
max-width: 100vw;
margin: 0;
padding: 0;
}
}
</style>

Some files were not shown because too many files have changed in this diff Show More