Clean up and working on the rich text editor. Will probably swap my version out for something else...
This commit is contained in:
@@ -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
14
package-lock.json
generated
@@ -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",
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -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 = '';
|
||||||
|
|||||||
@@ -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..."
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user