feat: Add form-based UI for event settings

This commit introduces form-based UI components for editing the 'cfg_json' and 'mod_pres_mgmt_json' fields on the event settings page. This provides a more user-friendly experience than editing the raw JSON directly. It also fixes an issue where the JSON objects were being displayed as '[object Object]'.
This commit is contained in:
Scott Idem
2025-11-18 19:17:27 -05:00
parent 0be878c8c1
commit f7d1f304fe
3 changed files with 131 additions and 22 deletions

View File

@@ -5,6 +5,9 @@
import { onMount } from 'svelte'; import { onMount } from 'svelte';
import { events_func } from '$lib/ae_events_functions'; import { events_func } from '$lib/ae_events_functions';
import { ae_api } from '$lib/stores/ae_stores'; import { ae_api } from '$lib/stores/ae_stores';
import E_app_codemirror_v5 from '$lib/app_components/e_app_codemirror_v5.svelte';
import Ae_comp_event_settings_form from './ae_comp__event_settings_form.svelte';
import Ae_comp_event_settings_pres_mgmt_form from './ae_comp__event_settings_pres_mgmt_form.svelte';
let event_id = $page.params.event_id; let event_id = $page.params.event_id;
let event_obj = $state(null); let event_obj = $state(null);
@@ -20,10 +23,11 @@
}; };
}); });
async function handle_save(field_name: string, json_string: string) { async function handle_save(field_name: string, json_data: string | object) {
try { try {
const parsed_json = JSON.parse(json_string); const data_to_save =
const data_kv = { [field_name]: parsed_json }; typeof json_data === 'string' ? JSON.parse(json_data) : json_data;
const data_kv = { [field_name]: data_to_save };
await events_func.update_ae_obj__event({ await events_func.update_ae_obj__event({
api_cfg: $ae_api, api_cfg: $ae_api,
@@ -45,28 +49,33 @@
<div class="space-y-4"> <div class="space-y-4">
<div> <div>
<h2 class="h2">General Config (cfg_json)</h2> <h2 class="h2">General Config (cfg_json)</h2>
<textarea class="textarea w-full h-64" bind:value={event_obj.cfg_json}></textarea> <Ae_comp_event_settings_form
<button cfg_json={event_obj.cfg_json}
class="btn preset-tonal-primary" on:save={(e) => handle_save('cfg_json', e.detail)}
on:click={() => handle_save('cfg_json', event_obj.cfg_json)}>Save</button />
>
</div> </div>
<div> <div>
<h2 class="h2">Presentation Management (mod_pres_mgmt_json)</h2> <h2 class="h2">Presentation Management (mod_pres_mgmt_json)</h2>
<textarea <Ae_comp_event_settings_pres_mgmt_form
class="textarea w-full h-64" mod_pres_mgmt_json={event_obj.mod_pres_mgmt_json}
bind:value={event_obj.mod_pres_mgmt_json}></textarea> on:save={(e) => handle_save('mod_pres_mgmt_json', e.detail)}
<button />
class="btn preset-tonal-primary"
on:click={() => handle_save('mod_pres_mgmt_json', event_obj.mod_pres_mgmt_json)}
>Save</button
>
</div> </div>
<div> <div>
<h2 class="h2">Badges (mod_badges_json)</h2> <h2 class="h2">Badges (mod_badges_json)</h2>
<textarea class="textarea w-full h-64" bind:value={event_obj.mod_badges_json}></textarea> <E_app_codemirror_v5
editable={true}
readonly={false}
content={JSON.stringify(event_obj.mod_badges_json, null, 4)}
show_line_numbers={true}
placeholder="JSON config"
class="p-1 preset-outlined-success-400-600 shadow-lg rounded-lg"
on:change={(e) => {
event_obj.mod_badges_json = e.detail;
}}
/>
<button <button
class="btn preset-tonal-primary" class="btn preset-tonal-primary"
on:click={() => handle_save('mod_badges_json', event_obj.mod_badges_json)}>Save</button on:click={() => handle_save('mod_badges_json', event_obj.mod_badges_json)}>Save</button
@@ -75,9 +84,17 @@
<div> <div>
<h2 class="h2">Abstracts (mod_abstracts_json)</h2> <h2 class="h2">Abstracts (mod_abstracts_json)</h2>
<textarea <E_app_codemirror_v5
class="textarea w-full h-64" editable={true}
bind:value={event_obj.mod_abstracts_json}></textarea> readonly={false}
content={JSON.stringify(event_obj.mod_abstracts_json, null, 4)}
show_line_numbers={true}
placeholder="JSON config"
class="p-1 preset-outlined-success-400-600 shadow-lg rounded-lg"
on:change={(e) => {
event_obj.mod_abstracts_json = e.detail;
}}
/>
<button <button
class="btn preset-tonal-primary" class="btn preset-tonal-primary"
on:click={() => handle_save('mod_abstracts_json', event_obj.mod_abstracts_json)} on:click={() => handle_save('mod_abstracts_json', event_obj.mod_abstracts_json)}
@@ -87,7 +104,17 @@
<div> <div>
<h2 class="h2">Exhibits (mod_exhibits_json)</h2> <h2 class="h2">Exhibits (mod_exhibits_json)</h2>
<textarea class="textarea w-full h-64" bind:value={event_obj.mod_exhibits_json}></textarea> <E_app_codemirror_v5
editable={true}
readonly={false}
content={JSON.stringify(event_obj.mod_exhibits_json, null, 4)}
show_line_numbers={true}
placeholder="JSON config"
class="p-1 preset-outlined-success-400-600 shadow-lg rounded-lg"
on:change={(e) => {
event_obj.mod_exhibits_json = e.detail;
}}
/>
<button <button
class="btn preset-tonal-primary" class="btn preset-tonal-primary"
on:click={() => handle_save('mod_exhibits_json', event_obj.mod_exhibits_json)} on:click={() => handle_save('mod_exhibits_json', event_obj.mod_exhibits_json)}
@@ -97,7 +124,17 @@
<div> <div>
<h2 class="h2">Meetings (mod_meetings_json)</h2> <h2 class="h2">Meetings (mod_meetings_json)</h2>
<textarea class="textarea w-full h-64" bind:value={event_obj.mod_meetings_json}></textarea> <E_app_codemirror_v5
editable={true}
readonly={false}
content={JSON.stringify(event_obj.mod_meetings_json, null, 4)}
show_line_numbers={true}
placeholder="JSON config"
class="p-1 preset-outlined-success-400-600 shadow-lg rounded-lg"
on:change={(e) => {
event_obj.mod_meetings_json = e.detail;
}}
/>
<button <button
class="btn preset-tonal-primary" class="btn preset-tonal-primary"
on:click={() => handle_save('mod_meetings_json', event_obj.mod_meetings_json)} on:click={() => handle_save('mod_meetings_json', event_obj.mod_meetings_json)}

View File

@@ -0,0 +1,34 @@
<script lang="ts">
import type { key_val } from '$lib/stores/ae_stores';
import { createEventDispatcher } from 'svelte';
interface Props {
cfg_json: key_val;
}
let { cfg_json }: Props = $props();
let local_cfg_json = $state(cfg_json);
const dispatch = createEventDispatcher();
function save() {
dispatch('save', local_cfg_json);
}
</script>
<div class="space-y-4">
<div>
<label class="label">
<span>Short Name</span>
<input type="text" class="input" bind:value={local_cfg_json.short_name} />
</label>
</div>
<div>
<label class="label">
<span>Medium Name</span>
<input type="text" class="input" bind:value={local_cfg_json.med_name} />
</label>
</div>
<button class="btn preset-tonal-primary" on:click={save}>Save</button>
</div>

View File

@@ -0,0 +1,38 @@
<script lang="ts">
import type { key_val } from '$lib/stores/ae_stores';
import { createEventDispatcher } from 'svelte';
interface Props {
mod_pres_mgmt_json: key_val;
}
let { mod_pres_mgmt_json }: Props = $props();
let local_mod_pres_mgmt_json = $state(mod_pres_mgmt_json);
const dispatch = createEventDispatcher();
function save() {
dispatch('save', local_mod_pres_mgmt_json);
}
</script>
<div class="space-y-4">
<div>
<label class="label">
<input type="checkbox" class="checkbox" bind:checked={local_mod_pres_mgmt_json.lock_config} />
<span>Lock Config</span>
</label>
</div>
<div>
<label class="label">
<input
type="checkbox"
class="checkbox"
bind:checked={local_mod_pres_mgmt_json.hide__location_code}
/>
<span>Hide Location Code</span>
</label>
</div>
<button class="btn preset-tonal-primary" on:click={save}>Save</button>
</div>