diff --git a/src/lib/ae_events__event.ts b/src/lib/ae_events__event.ts index 0dd16cf0..5d04199e 100644 --- a/src/lib/ae_events__event.ts +++ b/src/lib/ae_events__event.ts @@ -490,6 +490,10 @@ export function db_save_ae_obj_li__event( end_datetime: obj.end_datetime, timezone: obj.timezone, location_address_json: obj.location_address_json, + location_text: obj.location_text, + + attend_json: obj.attend_json, + attend_text: obj.attend_text, mod_abstracts_json: obj.mod_abstracts_json, mod_badges_json: obj.mod_badges_json, diff --git a/src/lib/ae_utils/ae_utils.ts b/src/lib/ae_utils/ae_utils.ts index 445da06e..3352a50c 100644 --- a/src/lib/ae_utils/ae_utils.ts +++ b/src/lib/ae_utils/ae_utils.ts @@ -3,6 +3,9 @@ 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 { clean_filename, format_bytes, guess_file_name, guess_file_extension, get_file_hash } from './ae_utils__files'; +import { get_obj_li_w_match_prop} from './ae_utils__get_obj_li_w_match_prop'; +import { extract_prefixed_form_data } from './ae_utils__extract_prefixed_form_data'; + type key_str = { [key: string]: string; @@ -19,113 +22,6 @@ function number_w_commas(x) { } -/* 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 @@ -716,6 +612,7 @@ export let ae_util = { guess_file_name: guess_file_name, guess_file_extension: guess_file_extension, get_file_hash: get_file_hash, + get_obj_li_w_match_prop: get_obj_li_w_match_prop, extract_prefixed_form_data: extract_prefixed_form_data, process_data_string: process_data_string, handle_url_and_message: handle_url_and_message, diff --git a/src/lib/ae_utils/ae_utils__extract_prefixed_form_data.ts b/src/lib/ae_utils/ae_utils__extract_prefixed_form_data.ts new file mode 100644 index 00000000..fa463cfd --- /dev/null +++ b/src/lib/ae_utils/ae_utils__extract_prefixed_form_data.ts @@ -0,0 +1,127 @@ +type key_val = { + [key: string]: any; +}; + +/* 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 + }: { + prefix: string|null, + form_data: any, + rm_empty_id?: boolean, + rm_empty?: boolean, + trim_values?: boolean, + bool_tf_str?: boolean, + log_lvl?: number + } + ) { + 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: key_val = {}; + 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; +} diff --git a/src/lib/ae_utils/ae_utils__get_obj_li_w_match_prop.ts b/src/lib/ae_utils/ae_utils__get_obj_li_w_match_prop.ts new file mode 100644 index 00000000..33e05fa6 --- /dev/null +++ b/src/lib/ae_utils/ae_utils__get_obj_li_w_match_prop.ts @@ -0,0 +1,46 @@ + +/* Returns a list of objects that have a matching property value. */ +// Updated 2023-06-28 +export let get_obj_li_w_match_prop = function get_obj_li_w_match_prop( + { + obj_li, + property, + value, + log_lvl = 0 + }: { + obj_li: any[], + property: string, + value: any, + log_lvl?: number + } + ) { + if (log_lvl) { + console.log('Search Object List:', obj_li); + console.log(`Property: ${property}`); + console.log(`Value: ${value}`); + } + if (log_lvl > 1) { + console.log(`Type Of: ${typeof value}`); + } + + // Create an empty array to store the matching objects. + const matching_obj_li = []; + + // Iterate through the list of objects. + for (const object of obj_li) { + // Check if the object has the specified property and the value of the property matches the specified value. + if (object.hasOwnProperty(property)) { + // console.log('Has property at least....', object[property], typeof object[property]); + } + if (object.hasOwnProperty(property) && object[property] === value) { + // Add the object to the array of matching objects. + matching_obj_li.push(object); + } + } + + // Return the array of matching objects. + if (log_lvl > 1) { + console.log('Matching Object List:', matching_obj_li); + } + return matching_obj_li; +} \ No newline at end of file diff --git a/src/lib/api.ts b/src/lib/api.ts index d4b21d10..e0926e81 100644 --- a/src/lib/api.ts +++ b/src/lib/api.ts @@ -319,7 +319,7 @@ export let update_ae_obj_id_crud = async function update_ae_obj_id_crud( return_obj = false, obj_v_name = '', return_meta = false, - log_lvl = 3 + log_lvl = 1 }: { api_cfg: any, obj_type: string, diff --git a/src/lib/db_events.ts b/src/lib/db_events.ts index 9c4958ec..6f43ab54 100644 --- a/src/lib/db_events.ts +++ b/src/lib/db_events.ts @@ -27,6 +27,10 @@ export interface Event { end_datetime?: Date; timezone?: null|string; location_address_json?: null|string; + location_text?: null|string; + + attend_json?: null|string; + attend_text?: null|string; mod_abstracts_json?: null|key_val; mod_badges_json?: null|key_val; diff --git a/src/lib/element_tiptap_editor.svelte b/src/lib/element_tiptap_editor.svelte index 0def55ca..0b34eb5b 100644 --- a/src/lib/element_tiptap_editor.svelte +++ b/src/lib/element_tiptap_editor.svelte @@ -5,6 +5,7 @@ import ListItem from '@tiptap/extension-list-item' import TextStyle from '@tiptap/extension-text-style' import StarterKit from "@tiptap/starter-kit"; import { Editor } from "@tiptap/core"; +// import Highlight from '@tiptap/extension-highlight'; // import Highlight from '@tiptap/extension-highlight' ???? // import Typography from '@tiptap/extension-typography' ???? @@ -16,6 +17,12 @@ import "./element_tiptap_editor.scss"; // export let html_text: string = ''; +export let default_minimal: boolean = false; +export let show_menu: boolean = true; + +if (default_minimal) { + show_menu = false; +} // export let html_text: string = ` //

@@ -74,19 +81,23 @@ if (show_button_kv) { show_button_kv = show_button_kv_defaults; } +export let new_json = editor?.getJSON(); +export let new_html: string = ''; + onMount(() => { editor = new Editor({ - element: element, - extensions: [ - Color.configure({ types: [TextStyle.name, ListItem.name] }), - TextStyle.configure({ types: [ListItem.name] }), - StarterKit, - ], - content: html_text, - onTransaction: () => { - // force re-render so `editor.isActive` works as expected - editor = editor; - }, + element: element, + extensions: [ + Color.configure({ types: [TextStyle.name, ListItem.name] }), + TextStyle.configure({ types: [ListItem.name] }), + StarterKit, + ], + content: html_text, + onTransaction: () => { + // force re-render so `editor.isActive` works as expected + editor = editor; + new_html = editor.getHTML(); + }, }); }); @@ -98,17 +109,28 @@ onDestroy(() => {
{ + if (default_minimal) { + editor.chain().focus().setParagraph().run(); + show_menu = true; + } + }} + on:mouseleave={() => { + if (default_minimal) { + show_menu = false; + } + }} class="editor border border-gray-300 rounded p-1 pb-2 bg-gray-200" > - {#if editor} + {#if editor && show_menu}