Clean up and working on the rich text editor. Will probably swap my version out for something else...

This commit is contained in:
Scott Idem
2024-12-02 14:56:22 -05:00
parent c0fe69ea73
commit 058c88c766
13 changed files with 290 additions and 201 deletions

View File

@@ -83,6 +83,11 @@ npm install --save-dev svelte-highlight typescript-svelte-plugin
npm install flowbite flowbite-svelte tailwind-merge @popperjs/core npm install flowbite flowbite-svelte tailwind-merge @popperjs/core
``` ```
More packages related to the Tiptap editor
```bash
npm install @tiptap/extension-link @tiptap/extension-bullet-list @tiptap/extension-history @tiptap/extension-typography @tiptap/extension-underline
```
## Build ## Build
## Environment file ## Environment file

14
package-lock.json generated
View File

@@ -20,6 +20,7 @@
"@tiptap/extension-paragraph": "^2.10.2", "@tiptap/extension-paragraph": "^2.10.2",
"@tiptap/extension-text": "^2.10.2", "@tiptap/extension-text": "^2.10.2",
"@tiptap/extension-typography": "^2.10.2", "@tiptap/extension-typography": "^2.10.2",
"@tiptap/extension-underline": "^2.10.3",
"@tiptap/pm": "^2.10.2", "@tiptap/pm": "^2.10.2",
"@tiptap/starter-kit": "^2.10.2", "@tiptap/starter-kit": "^2.10.2",
"axios": "^1.7.0", "axios": "^1.7.0",
@@ -1728,6 +1729,19 @@
"@tiptap/core": "^2.7.0" "@tiptap/core": "^2.7.0"
} }
}, },
"node_modules/@tiptap/extension-underline": {
"version": "2.10.3",
"resolved": "https://registry.npmjs.org/@tiptap/extension-underline/-/extension-underline-2.10.3.tgz",
"integrity": "sha512-VeGs0jeNiTnXddHHJEgOc/sKljZiyTEgSSuqMmsBACrr9aGFXbLTgKTvNjkZ9WzSnu7LwgJuBrwEhg8yYixUyQ==",
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/ueberdosis"
},
"peerDependencies": {
"@tiptap/core": "^2.7.0"
}
},
"node_modules/@tiptap/pm": { "node_modules/@tiptap/pm": {
"version": "2.10.2", "version": "2.10.2",
"resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-2.10.2.tgz", "resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-2.10.2.tgz",

View File

@@ -67,6 +67,7 @@
"@tiptap/extension-paragraph": "^2.10.2", "@tiptap/extension-paragraph": "^2.10.2",
"@tiptap/extension-text": "^2.10.2", "@tiptap/extension-text": "^2.10.2",
"@tiptap/extension-typography": "^2.10.2", "@tiptap/extension-typography": "^2.10.2",
"@tiptap/extension-underline": "^2.10.3",
"@tiptap/pm": "^2.10.2", "@tiptap/pm": "^2.10.2",
"@tiptap/starter-kit": "^2.10.2", "@tiptap/starter-kit": "^2.10.2",
"axios": "^1.7.0", "axios": "^1.7.0",

View File

@@ -331,7 +331,7 @@ export async function qry_ae_obj_li__event(
} }
// Updated 2024-09-25 // Updated 2024-12-02
export async function create_ae_obj__event( export async function create_ae_obj__event(
{ {
api_cfg, api_cfg,
@@ -371,7 +371,8 @@ export async function create_ae_obj__event(
db_save_ae_obj_li__event( db_save_ae_obj_li__event(
{ {
obj_type: 'event', obj_type: 'event',
obj_li: [event_obj_create_result] obj_li: [event_obj_create_result],
log_lvl: log_lvl
}); });
} }
return event_obj_create_result; return event_obj_create_result;

View File

@@ -1,102 +1,113 @@
/* Basic editor styles */ /* Basic editor styles */
.tiptap { .tiptap {
:first-child { :first-child {
margin-top: 0; margin-top: 0;
}
/* List styles */
ul {
list-style-type: disc;
margin-left: 1.5rem;
// border: solid thin red;
}
ol {
list-style-type: decimal;
margin-left: 1.5rem;
// border: solid thin red;
}
ul,
ol {
padding: 0 1rem;
margin: 1.25rem 1rem 1.25rem 0.4rem;
li p {
margin-top: 0.25em;
margin-bottom: 0.25em;
} }
}
/* Heading styles */ /* Link styles */
h1, a {
h2, color: var(--purple);
h3, cursor: pointer;
h4, text-decoration: underline;
h5,
h6 {
line-height: 1.1;
margin-top: 2.5rem;
text-wrap: pretty;
}
h1, &:hover {
h2 { color: var(--purple-contrast);
margin-top: 3.5rem; }
margin-bottom: 1.5rem; }
}
h1 { /* List styles */
font-size: 1.4rem; ul {
} list-style-type: disc;
margin-left: 1.5rem;
// border: solid thin red;
}
ol {
list-style-type: decimal;
margin-left: 1.5rem;
// border: solid thin red;
}
h2 { ul,
font-size: 1.2rem; ol {
} padding: 0 1rem;
margin: 1.25rem 1rem 1.25rem 0.4rem;
h3 { li p {
font-size: 1.1rem; margin-top: 0.25em;
} margin-bottom: 0.25em;
}
}
h4, /* Heading styles */
h5, h1,
h6 { h2,
font-size: 1rem; h3,
} h4,
h5,
h6 {
line-height: 1.1;
margin-top: 2.5rem;
text-wrap: pretty;
}
/* Code and preformatted text styles */ h1,
code { h2 {
background-color: var(--purple-light); margin-top: 3.5rem;
border-radius: 0.4rem; margin-bottom: 1.5rem;
color: var(--black); }
font-size: 0.85rem;
padding: 0.25em 0.3em;
}
pre { h1 {
background: var(--black); font-size: 1.4rem;
border-radius: 0.5rem; }
color: var(--white);
font-family: 'JetBrainsMono', monospace;
margin: 1.5rem 0;
padding: 0.75rem 1rem;
h2 {
font-size: 1.2rem;
}
h3 {
font-size: 1.1rem;
}
h4,
h5,
h6 {
font-size: 1rem;
}
/* Code and preformatted text styles */
code { code {
background: none; background-color: var(--purple-light);
color: inherit; border-radius: 0.4rem;
font-size: 0.8rem; color: var(--black);
padding: 0; font-size: 0.85rem;
padding: 0.25em 0.3em;
} }
}
blockquote { pre {
border-left: 3px solid var(--gray-3); background: var(--black);
margin: 1.5rem 0; border-radius: 0.5rem;
padding-left: 1rem; color: var(--white);
} font-family: 'JetBrainsMono', monospace;
margin: 1.5rem 0;
padding: 0.75rem 1rem;
hr { code {
border: none; background: none;
border-top: 1px solid var(--gray-2); color: inherit;
margin: 2rem 0; font-size: 0.8rem;
} padding: 0;
}
}
blockquote {
border-left: 3px solid var(--gray-3);
margin: 1.5rem 0;
padding-left: 1rem;
}
hr {
border: none;
border-top: 1px solid var(--gray-2);
margin: 2rem 0;
}
} }

View File

@@ -24,6 +24,7 @@ import Strike from '@tiptap/extension-strike';
import Text from '@tiptap/extension-text'; import Text from '@tiptap/extension-text';
import TextStyle from '@tiptap/extension-text-style'; import TextStyle from '@tiptap/extension-text-style';
import Typography from '@tiptap/extension-typography'; import Typography from '@tiptap/extension-typography';
import Underline from '@tiptap/extension-underline';
import "./element_tiptap_editor.scss"; import "./element_tiptap_editor.scss";
@@ -125,10 +126,11 @@ onMount(() => {
CodeBlock, // part of StarterKit CodeBlock, // part of StarterKit
Italic, // part of StarterKit Italic, // part of StarterKit
Strike, // part of StarterKit Strike, // part of StarterKit
Underline, // part of StarterKit
BulletList, // part of StarterKit BulletList, // part of StarterKit
Color.configure({ types: [TextStyle.name, ListItem.name] }), // Color.configure({ types: [TextStyle.name, ListItem.name] }),
TextStyle.configure({ types: [ListItem.name] }), // TextStyle.configure({ types: [ListItem.name] }),
Heading.configure({ levels: [1, 2, 3, 4, 5, 6] }), // Heading.configure({ levels: [1, 2, 3, 4, 5, 6] }),
Highlight, Highlight,
History.configure({ History.configure({
depth: 100, depth: 100,
@@ -141,56 +143,56 @@ onMount(() => {
protocols: ['http', 'https'], protocols: ['http', 'https'],
isAllowedUri: (url, ctx) => { isAllowedUri: (url, ctx) => {
try { try {
// construct URL // construct URL
const parsedUrl = url.includes(':') ? new URL(url) : new URL(`${ctx.defaultProtocol}://${url}`) const parsedUrl = url.includes(':') ? new URL(url) : new URL(`${ctx.defaultProtocol}://${url}`)
// use default validation // use default validation
if (!ctx.defaultValidate(parsedUrl.href)) { if (!ctx.defaultValidate(parsedUrl.href)) {
return false
}
// disallowed protocols
const disallowedProtocols = ['ftp', 'file', 'mailto']
const protocol = parsedUrl.protocol.replace(':', '')
if (disallowedProtocols.includes(protocol)) {
return false
}
// only allow protocols specified in ctx.protocols
const allowedProtocols = ctx.protocols.map(p => (typeof p === 'string' ? p : p.scheme))
if (!allowedProtocols.includes(protocol)) {
return false
}
// disallowed domains
const disallowedDomains = ['example-phishing.com', 'malicious-site.net']
const domain = parsedUrl.hostname
if (disallowedDomains.includes(domain)) {
return false
}
// all checks have passed
return true
} catch (error) {
return false return false
} }
// disallowed protocols
const disallowedProtocols = ['ftp', 'file', 'mailto']
const protocol = parsedUrl.protocol.replace(':', '')
if (disallowedProtocols.includes(protocol)) {
return false
}
// only allow protocols specified in ctx.protocols
const allowedProtocols = ctx.protocols.map(p => (typeof p === 'string' ? p : p.scheme))
if (!allowedProtocols.includes(protocol)) {
return false
}
// disallowed domains
const disallowedDomains = ['example-phishing.com', 'malicious-site.net']
const domain = parsedUrl.hostname
if (disallowedDomains.includes(domain)) {
return false
}
// all checks have passed
return true
} catch (error) {
return false
}
}, },
shouldAutoLink: url => { shouldAutoLink: url => {
try { try {
// construct URL // construct URL
const parsedUrl = url.includes(':') ? new URL(url) : new URL(`https://${url}`) const parsedUrl = url.includes(':') ? new URL(url) : new URL(`https://${url}`)
// only auto-link if the domain is not in the disallowed list // only auto-link if the domain is not in the disallowed list
const disallowedDomains = ['example-no-autolink.com', 'another-no-autolink.com'] const disallowedDomains = ['example-no-autolink.com', 'another-no-autolink.com']
const domain = parsedUrl.hostname const domain = parsedUrl.hostname
return !disallowedDomains.includes(domain) return !disallowedDomains.includes(domain)
} catch (error) { } catch (error) {
return false return false
} }
}, },
}), }),
ListItem, ListItem,
@@ -201,18 +203,20 @@ onMount(() => {
Typography, Typography,
], ],
content: html_text, content: html_text,
onTransaction: () => { onTransaction: ({ editor, transaction }) => {
// console.log('onTransaction');
// force re-render so `editor.isActive` works as expected // force re-render so `editor.isActive` works as expected
editor = editor; // editor = editor;
let updated_html = editor.getHTML(); // let updated_html = editor.getHTML();
if (updated_html == '<p></p>') { // if (updated_html == '<p></p>') {
new_html = ''; // new_html = '';
} else { // } else {
new_html = updated_html; // new_html = updated_html;
} // }
}, },
onUpdate: ({ editor }) => { onUpdate: ({ editor }) => {
console.log('onUpdate', editor.getHTML());
let updated_html = editor.getHTML(); let updated_html = editor.getHTML();
if (updated_html == '<p></p>') { if (updated_html == '<p></p>') {
new_html = ''; new_html = '';

View File

@@ -330,7 +330,7 @@ function send_poster_notification_email() {
<Tiptap_editor <Tiptap_editor
default_minimal={true} default_minimal={true}
bind:html_text={$idaa_slct.post_comment_obj.content} bind:html_text={$idaa_slct.post_comment_obj.content}
show_button_kv={{'heading__h1': true, 'heading__h2': false, 'heading__h3': false}} show_button_kv={{'heading__h1': false, 'heading__h2': false, 'heading__h3': false}}
bind:new_html={$idaa_slct.post_comment_obj.content_new_html} bind:new_html={$idaa_slct.post_comment_obj.content_new_html}
placeholder="Your post content here..." placeholder="Your post content here..."
/> />

View File

@@ -40,7 +40,7 @@ async function handle_submit_form(event: any) {
console.log(form_data); console.log(form_data);
} }
// Form Post object data incoming // Form Post object data incoming
let post_di = ae_util.extract_prefixed_form_data({prefix: null, form_data: form_data, trim_values: true, bool_tf_str: true, log_lvl: log_lvl}); let post_di = ae_util.extract_prefixed_form_data({prefix: null, form_data: form_data, trim_values: true, bool_tf_str: true, log_lvl: log_lvl});
// console.log(post_di); // console.log(post_di);
@@ -123,6 +123,9 @@ async function handle_submit_form(event: any) {
return false; return false;
} }
if (log_lvl) {
console.log('post_obj_create_result:', post_obj_create_result);
}
$idaa_slct.post_id = post_obj_create_result.post_id_random; $idaa_slct.post_id = post_obj_create_result.post_id_random;
$idaa_slct.post_obj = post_obj_create_result; $idaa_slct.post_obj = post_obj_create_result;
@@ -143,7 +146,9 @@ async function handle_submit_form(event: any) {
}); });
return prom_api__post_obj; return prom_api__post_obj;
} else { } else {
prom_api__post_obj = posts_func.update_ae_obj__post({ prom_api__post_obj = posts_func.update_ae_obj__post({
api_cfg: $ae_api, api_cfg: $ae_api,
post_id: $idaa_slct.post_id, post_id: $idaa_slct.post_id,
@@ -177,6 +182,7 @@ async function handle_submit_form(event: any) {
}); });
return prom_api__post_obj; return prom_api__post_obj;
} }
} }
@@ -349,13 +355,33 @@ function send_staff_notification_email() {
</span> </span>
<!-- <textarea name="content" id="content" class="ae_value post__content tinymce_editor editor_basic textarea" rows="5" cols="70" bind:value={$idaa_slct.post_obj.content} ></textarea> --> <!-- <textarea name="content" id="content" class="ae_value post__content tinymce_editor editor_basic textarea" rows="5" cols="70" bind:value={$idaa_slct.post_obj.content} ></textarea> -->
<Tiptap_editor {#if $ae_loc.administrator_access}
default_minimal={true} <Tiptap_editor
bind:html_text={$idaa_slct.post_obj.content} default_minimal={true}
show_button_kv={{'heading__h1': false, 'heading__h2': false, 'heading__h3': false}} bind:html_text={$idaa_slct.post_obj.content}
bind:new_html={$idaa_slct.post_obj.content_new_html} show_button_kv={{'heading__h1': true, 'heading__h2': true, 'heading__h3': true}}
placeholder="Your post content here..." bind:new_html={$idaa_slct.post_obj.content_new_html}
/> placeholder="Your post content here..."
/>
{:else}
<Tiptap_editor
default_minimal={true}
bind:html_text={$idaa_slct.post_obj.content}
show_button_kv={{
'heading__h1': false,
'heading__h2': false,
'heading__h3': false,
paragraph: false,
bulletList: false,
orderedList: false,
hardBreak: false,
link: false,
unsetLink: false
}}
bind:new_html={$idaa_slct.post_obj.content_new_html}
placeholder="Your post content here..."
/>
{/if}
</label> </label>

View File

@@ -300,8 +300,7 @@ $: if ($idaa_trig.event_li_qry) {
</section> </section>
<!-- Modal: Event (Recovery Meeting) edit ID -->
<!-- Main modal -->
<Modal <Modal
title="{$lq__event_obj?.name} - {$lq__event_obj?.id}" title="{$lq__event_obj?.name} - {$lq__event_obj?.id}"
bind:open={$idaa_sess.recovery_meetings.show__modal_edit} bind:open={$idaa_sess.recovery_meetings.show__modal_edit}
@@ -314,26 +313,28 @@ $: if ($idaa_trig.event_li_qry) {
<svelte:fragment slot="header"> <svelte:fragment slot="header">
<div class="flex flex-row items-center justify-between w-full"> <div class="flex flex-row items-center justify-between w-full">
<h3 class="text-lg font-semibold"> <h3 class="text-lg font-semibold">
{#if $ae_loc.trusted_access || $lq__event_obj?.external_person_id === $idaa_loc.novi_uuid || $lq__event_obj?.contact_li_json[0]?.email === $idaa_loc.novi_email} {#if $ae_loc.trusted_access || $lq__event_obj?.external_person_id === $idaa_loc.novi_uuid || $lq__event_obj?.contact_li_json[0]?.email === $idaa_loc.novi_email}
<!-- <div class="ae_options"> --> <!-- <div class="ae_options"> -->
<button <button
on:click={() => { on:click={() => {
// const url = new URL(location); // const url = new URL(location);
// url.searchParams.set('event_id', $lq__event_obj?.event_id_random); // url.searchParams.set('event_id', $lq__event_obj?.event_id_random);
// history.pushState({}, '', url); // history.pushState({}, '', url);
$idaa_sess.recovery_meetings.show__modal_view = true; $idaa_sess.recovery_meetings.show__modal_edit = false;
$idaa_sess.recovery_meetings.show__modal_edit = false; $idaa_sess.recovery_meetings.show__modal_view = true;
}} }}
class="btn btn-sm variant-ghost-warning hover:variant-filled-warning transition" class="btn btn-sm variant-ghost-warning hover:variant-filled-warning transition"
title={`View meeting: ${$lq__event_obj?.name}`} title={`View meeting: ${$lq__event_obj?.name}`}
> >
<span class="fas fa-eye m-1"></span> View <span class="fas fa-times m-1"></span> Cancel Edit
</button> </button>
<!-- </div> --> <!-- </div> -->
{/if} {/if}
Edit Meeting: {$lq__event_obj?.name}</h3> <span class="fas fa-calendar-day m-1"></span>
{$lq__event_obj?.name ?? 'New Recovery Meeting'}
</h3>
</div> </div>
</svelte:fragment> </svelte:fragment>
@@ -361,6 +362,7 @@ $: if ($idaa_trig.event_li_qry) {
</Modal> </Modal>
<!-- Modal: Event (Recovery Meeting) view ID --> <!-- Modal: Event (Recovery Meeting) view ID -->
<Modal <Modal
title="{$lq__event_obj?.name} - {$lq__event_obj?.id}" title="{$lq__event_obj?.name} - {$lq__event_obj?.id}"
@@ -392,7 +394,8 @@ $: if ($idaa_trig.event_li_qry) {
<span class="fas fa-edit m-1"></span> Edit <span class="fas fa-edit m-1"></span> Edit
</button> </button>
{/if} {/if}
{$lq__event_obj?.name} <span class="fas fa-calendar-day m-1"></span>
{$lq__event_obj?.name ?? '-- not set'}
</h3> </h3>
</div> </div>
</svelte:fragment> </svelte:fragment>
@@ -401,4 +404,4 @@ $: if ($idaa_trig.event_li_qry) {
lq__event_obj={lq__event_obj} lq__event_obj={lq__event_obj}
/> />
</Modal> </Modal>

View File

@@ -238,12 +238,16 @@ async function handle_submit_form(event: any) {
disable_submit_btn = true; disable_submit_btn = true;
let form_data = new FormData(event.target); let form_data = new FormData(event.target);
console.log(form_data); if (log_lvl) {
console.log(form_data);
}
let event_meeting_fd = ae_util.extract_prefixed_form_data({prefix: null, form_data: form_data, trim_values: true, bool_tf_str: true, log_lvl: 0}); // Form Event object data incoming
console.log(event_meeting_fd); let event_meeting_fd = ae_util.extract_prefixed_form_data({prefix: null, form_data: form_data, trim_values: true, bool_tf_str: true, log_lvl: log_lvl});
// console.log(event_meeting_fd);
let event_do: key_val = {}; // Data out for API object // Form Event object data outgoing
let event_do: key_val = {};
if (!$idaa_slct.event_id) { if (!$idaa_slct.event_id) {
event_do['account_id_random'] = $ae_loc.account_id; event_do['account_id_random'] = $ae_loc.account_id;
@@ -429,21 +433,23 @@ async function handle_submit_form(event: any) {
console.log(event_do); console.log(event_do);
if (!$idaa_slct.event_id) { if (!$idaa_slct.event_id) {
prom_api__event_obj = api.create_ae_obj_crud({ prom_api__event_obj = events_func.create_ae_obj__event({
api_cfg: $ae_api, api_cfg: $ae_api,
obj_type: 'event', account_id: $ae_loc.account_id,
fields: event_do, data_kv: event_do,
key: $ae_api.api_crud_super_key, log_lvl: log_lvl
log_lvl: 1
}) })
.then(function (event_obj_create_result) { .then(function (event_obj_create_result) {
if (!event_obj_create_result) { if (!event_obj_create_result) {
console.log('The result was null or false.'); console.log('The result was null or false.');
return false; return false;
} }
console.log(event_obj_create_result);
if (log_lvl) {
console.log('event_obj_create_result:', event_obj_create_result);
}
$idaa_slct.event_id = event_obj_create_result.obj_id_random; $idaa_slct.event_id = event_obj_create_result.obj_id_random;
$idaa_slct.event_obj = event_obj_create_result;
return event_obj_create_result; return event_obj_create_result;
}) })
@@ -454,11 +460,14 @@ async function handle_submit_form(event: any) {
}) })
.finally(() => { .finally(() => {
disable_submit_btn = false; disable_submit_btn = false;
$idaa_sess.recovery_meetings.show__modal_edit = false;
$idaa_sess.recovery_meetings.show__modal_view = true;
}); });
return prom_api__event_obj; return prom_api__event_obj;
} else { } else {
prom_api__event_obj = events_func.update_ae_obj__event({ prom_api__event_obj = events_func.update_ae_obj__event({
api_cfg: $ae_api, api_cfg: $ae_api,
event_id: $idaa_slct.event_id, event_id: $idaa_slct.event_id,
@@ -483,6 +492,7 @@ async function handle_submit_form(event: any) {
}); });
return prom_api__event_obj; return prom_api__event_obj;
} }
} }
@@ -509,6 +519,7 @@ async function handle_delete_event_obj(
}) })
.then(function (event_obj_delete_result) { .then(function (event_obj_delete_result) {
$idaa_sess.recovery_meetings.show__modal_edit = false; $idaa_sess.recovery_meetings.show__modal_edit = false;
$idaa_sess.recovery_meetings.show__modal_view = false;
}) })
.catch(function (error) { .catch(function (error) {
console.log('The result was null or false when trying to delete.', error); console.log('The result was null or false when trying to delete.', error);

View File

@@ -54,12 +54,12 @@ onDestroy(() => {
<div class="p-2 bg-white shadow-md rounded-lg"> <div class="p-2 bg-white shadow-md rounded-lg">
<div class="meeting_description description mb-4"> <div class="meeting_description description mb-4">
<div class="ae_label event__description font-semibold text-lg mb-2">Description:</div> <div class="ae_label event__description mb-2">Description:</div>
<pre class="ae_value event__description text-wrap font-normal whitespace-pre-wrap">{@html $lq__event_obj?.description}</pre> <pre class="ae_value event__description text-wrap font-normal whitespace-pre-wrap">{@html $lq__event_obj?.description}</pre>
</div> </div>
<div class:ae_d_none={!$lq__event_obj?.type} class="meeting_type mb-4"> <div class:hidden={!$lq__event_obj?.type} class="meeting_type mb-4">
<span class="ae_label font-semibold text-lg">Type of Recovery Meeting:</span> <span class="ae_label">Type of Recovery Meeting:</span>
<span class="ae_value ml-2">{$lq__event_obj?.type}</span> <span class="ae_value ml-2">{$lq__event_obj?.type}</span>
</div> </div>
</div> </div>
@@ -67,11 +67,13 @@ onDestroy(() => {
<div class="p-2 bg-white shadow-md rounded-lg meeting_physical_virtual how_to_attended"> <div class="p-2 bg-white shadow-md rounded-lg meeting_physical_virtual how_to_attended">
<div class="col-6 meeting_physical" <div class="col-6 meeting_physical"
class:ae_d_none={(!$lq__event_obj?.address_city && !$lq__event_obj?.location_address_json) || ($lq__event_obj?.location_address_json && !$lq__event_obj?.location_address_json.city && !$lq__event_obj?.location_address_json.country_subdivision_code && !$lq__event_obj?.location_address_json.postal_code)} class:hidden={(!$lq__event_obj?.address_city && !$lq__event_obj?.location_address_json) || ($lq__event_obj?.location_address_json && !$lq__event_obj?.location_address_json.city && !$lq__event_obj?.location_address_json.country_subdivision_code && !$lq__event_obj?.location_address_json.postal_code)}
> >
<div class="meeting_address_location"> <div class="meeting_address_location">
<span class="ae_label">
Address: Address:
<address class="ae_value event__address"> </span>
<address class="ae_value_semi event__address">
{#if $lq__event_obj?.location_address_json} {#if $lq__event_obj?.location_address_json}
{#if $lq__event_obj?.physical} {#if $lq__event_obj?.physical}
@@ -112,9 +114,12 @@ onDestroy(() => {
</address> </address>
{#if $lq__event_obj?.physical} {#if $lq__event_obj?.physical}
<div <div
class:ae_d_none={!$lq__event_obj?.location_text} class:hidden={!$lq__event_obj?.location_text}
> >
Additional information: {@html $lq__event_obj?.location_text} <span class="ae_label">
Additional information:
</span>
<span class="ae_value_semi">{@html $lq__event_obj?.location_text}</span>
</div> </div>
{/if} {/if}
</div> </div>
@@ -122,10 +127,10 @@ onDestroy(() => {
<div class="col-6" <div class="col-6"
class:meeting_virtual={$lq__event_obj?.virtual} class:meeting_virtual={$lq__event_obj?.virtual}
class:ae_d_none={!$lq__event_obj?.virtual} class:hidden={!$lq__event_obj?.virtual}
> >
<div class="meeting_attend_url" <div class="meeting_attend_url"
class:ae_d_none={!$lq__event_obj?.attend_url} class:hidden={!$lq__event_obj?.attend_url}
> >
<span class="ae_label"> <span class="ae_label">
<span class="fas fa-link"></span> <span class="fas fa-link"></span>
@@ -146,7 +151,7 @@ onDestroy(() => {
</span> </span>
</div> </div>
<div class="meeting_attend_phone" <div class="meeting_attend_phone"
class:ae_d_none={!$lq__event_obj?.attend_phone} class:hidden={!$lq__event_obj?.attend_phone}
> >
<span class="ae_label"> <span class="ae_label">
<span class="fas fa-phone"></span> <span class="fas fa-phone"></span>
@@ -164,9 +169,12 @@ onDestroy(() => {
</span> </span>
</div> </div>
<div class="attend_text" <div class="attend_text"
class:ae_d_none={!$lq__event_obj?.attend_text} class:hidden={!$lq__event_obj?.attend_text}
> >
Additional information: {@html $lq__event_obj?.attend_text} <span class="ae_label">
Additional information:
</span>
<span class="ae_value_semi">{@html $lq__event_obj?.attend_text}</span>
</div> </div>
</div> </div>
@@ -219,7 +227,7 @@ onDestroy(() => {
<span class="ae_value">{ae_util.iso_datetime_formatter(`2024-01-01 ${$lq__event_obj?.recurring_start_time}`, 'time_12_short')}</span> <span class="ae_value">{ae_util.iso_datetime_formatter(`2024-01-01 ${$lq__event_obj?.recurring_start_time}`, 'time_12_short')}</span>
</span> </span>
<span <span
class:ae_d_none={!$lq__event_obj?.recurring_end_time} class:hidden={!$lq__event_obj?.recurring_end_time}
> >
- <span class="meeting_recurring_end_time"> - <span class="meeting_recurring_end_time">
<span class="ae_label">End time:</span> <span class="ae_label">End time:</span>
@@ -228,7 +236,7 @@ onDestroy(() => {
</span> </span>
</span> </span>
<span <span
class:ae_d_none={!$lq__event_obj?.timezone} class:hidden={!$lq__event_obj?.timezone}
> >
- <span class="meeting_timezone"> - <span class="meeting_timezone">
<span class="ae_label">Timezone:</span> <span class="ae_label">Timezone:</span>
@@ -263,7 +271,7 @@ onDestroy(() => {
{#if $lq__event_obj?.contact_li_json && $lq__event_obj?.contact_li_json.length && $lq__event_obj?.contact_li_json[0].full_name} {#if $lq__event_obj?.contact_li_json && $lq__event_obj?.contact_li_json.length && $lq__event_obj?.contact_li_json[0].full_name}
<div class="event__contact" <div class="event__contact"
class:ae_d_none={!$lq__event_obj?.contact_li_json[0].full_name} class:hidden={!$lq__event_obj?.contact_li_json[0].full_name}
> >
<span class="ae_label"> <span class="ae_label">
<span class="fas fa-user"></span> Contact: <span class="fas fa-user"></span> Contact:
@@ -294,7 +302,7 @@ onDestroy(() => {
{#if $lq__event_obj?.contact_li_json && $lq__event_obj?.contact_li_json.length && $lq__event_obj?.contact_li_json[1].full_name} {#if $lq__event_obj?.contact_li_json && $lq__event_obj?.contact_li_json.length && $lq__event_obj?.contact_li_json[1].full_name}
<div class="event__contact" <div class="event__contact"
class:ae_d_none={!$lq__event_obj?.contact_li_json[1].full_name} class:hidden={!$lq__event_obj?.contact_li_json[1].full_name}
> >
<span class="ae_label"> <span class="ae_label">
<span class="fas fa-user"></span> Contact: <span class="fas fa-user"></span> Contact:
@@ -328,7 +336,7 @@ onDestroy(() => {
<section class="ae_section ae_meta event__meta text-sm text-gray-500 mt-4 flex flex-row gap-2 items-center justify-center"> <section class="ae_section ae_meta event__meta text-sm text-gray-500 mt-4 flex flex-row gap-2 items-center justify-center">
<span <span
class="event__id" class="event__id"
class:ae_d_none={!$ae_loc.administrator_access}> class:hidden={!$ae_loc.administrator_access}>
ID: ID:
{$lq__event_obj?.event_id_random} {$lq__event_obj?.event_id_random}
</span> </span>
@@ -339,7 +347,7 @@ onDestroy(() => {
</span> </span>
<span <span
class="event__updated_on" class="event__updated_on"
class:ae_d_none={!$lq__event_obj?.updated_on} class:hidden={!$lq__event_obj?.updated_on}
> >
Updated on: {ae_util.iso_datetime_formatter($lq__event_obj?.updated_on, 'datetime_12_short')} Updated on: {ae_util.iso_datetime_formatter($lq__event_obj?.updated_on, 'datetime_12_short')}
</span> </span>
@@ -358,6 +366,9 @@ onDestroy(() => {
.ae_value { .ae_value {
font-weight: bold; font-weight: bold;
} }
.ae_value_semi {
font-weight: semi-bold;
}
.event__user_timezone { .event__user_timezone {
font-size: smaller; font-size: smaller;

View File

@@ -50,7 +50,9 @@ onMount(() => {
<header class="ae_header"> <header class="ae_header">
<h3 <h3
class="flex flex-row gap-2 items-center"> class="flex flex-row gap-2 items-center">
<span class="event__name h3">{idaa_event_obj?.name}</span> <span class="event__name h3">
<span class="fas fa-calendar-day m-1"></span>
{idaa_event_obj?.name}</span>
<span class="badge badge-info variant-glass-tertiary"> <span class="badge badge-info variant-glass-tertiary">
{#if idaa_event_obj?.physical && idaa_event_obj?.virtual} {#if idaa_event_obj?.physical && idaa_event_obj?.virtual}
<span class="fas fa-home m-1"></span> F2F and <span class="fas fa-laptop m-1"></span> Virtual <span class="fas fa-home m-1"></span> F2F and <span class="fas fa-laptop m-1"></span> Virtual

View File

@@ -519,7 +519,7 @@ if ($idaa_loc.recovery_meetings.qry__fulltext_str && $idaa_loc.recovery_meetings
$idaa_sess.recovery_meetings.show__modal_edit = true; $idaa_sess.recovery_meetings.show__modal_edit = true;
}} }}
class="btn_new_recovery_meeting btn btn-sm variant-ghost-warning hover:variant-filled-warning transition text-xs" class="btn_new_recovery_meeting btn btn-sm variant-ghost-warning hover:variant-filled-warning transition text-xs"
disabled={!$ae_loc.administrator_access} disabled={!$ae_loc.authenticated_access}
> >
<span class="fas fa-plus m-1"></span> Create New Meeting <span class="fas fa-plus m-1"></span> Create New Meeting
</button> </button>