feat(pres_mgmt): restore location and description editing in session view
Event location (FK lookup) and description were both visible in the session view but had no edit controls — lost during V3 migration. Restored both: - event_location_id: select dropdown populated from this event's location list (liveQuery on db_events.location filtered by event_id from the session object) - description: textarea editor shown directly in edit_mode (no collapse needed when actively editing) Also added event_location_id to editable_fields__event_session, which was missing and would have caused backend rejections on PATCH. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,7 @@ export const editable_fields__event_session = [
|
|||||||
'external_id',
|
'external_id',
|
||||||
'code',
|
'code',
|
||||||
'type_code',
|
'type_code',
|
||||||
|
'event_location_id',
|
||||||
'poc_agree',
|
'poc_agree',
|
||||||
'poc_kv_json',
|
'poc_kv_json',
|
||||||
'name',
|
'name',
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ let {
|
|||||||
|
|
||||||
// Imports
|
// Imports
|
||||||
import { Modal } from 'flowbite-svelte';
|
import { Modal } from 'flowbite-svelte';
|
||||||
|
import { liveQuery } from 'dexie';
|
||||||
import type { key_val } from '$lib/stores/ae_stores';
|
import type { key_val } from '$lib/stores/ae_stores';
|
||||||
import { ae_util } from '$lib/ae_utils/ae_utils';
|
import { ae_util } from '$lib/ae_utils/ae_utils';
|
||||||
import Element_ae_obj_field_editor from '$lib/elements/element_ae_obj_field_editor.svelte';
|
import Element_ae_obj_field_editor from '$lib/elements/element_ae_obj_field_editor.svelte';
|
||||||
@@ -29,6 +30,7 @@ import {
|
|||||||
events_slct
|
events_slct
|
||||||
} from '$lib/stores/ae_events_stores';
|
} from '$lib/stores/ae_events_stores';
|
||||||
import { events_func } from '$lib/ae_events/ae_events_functions';
|
import { events_func } from '$lib/ae_events/ae_events_functions';
|
||||||
|
import { db_events } from '$lib/ae_events/db_events';
|
||||||
|
|
||||||
import Comp_event_session_poc_profile from './ae_comp__event_session_poc_profile.svelte';
|
import Comp_event_session_poc_profile from './ae_comp__event_session_poc_profile.svelte';
|
||||||
import Comp_event_session_poc_form_agree from './ae_comp__event_session_poc_form_agree.svelte';
|
import Comp_event_session_poc_form_agree from './ae_comp__event_session_poc_form_agree.svelte';
|
||||||
@@ -52,6 +54,29 @@ $events_sess.pres_mgmt.show_content__presenter_start = false;
|
|||||||
// Description expand/collapse — collapsed by default (descriptions can be long)
|
// Description expand/collapse — collapsed by default (descriptions can be long)
|
||||||
let desc_expanded = $state(false);
|
let desc_expanded = $state(false);
|
||||||
|
|
||||||
|
// Location list for the session's event — used to build the select options in edit mode.
|
||||||
|
// WHY: event_location_id is a FK; the editor needs the full list so staff can pick from
|
||||||
|
// known rooms instead of typing a raw UUID. Keyed by event_id from the session object.
|
||||||
|
let current_event_id = $derived($lq__event_session_obj?.event_id ?? null);
|
||||||
|
let lq__event_location_obj_li = $derived(
|
||||||
|
liveQuery(async () => {
|
||||||
|
if (!current_event_id) return [];
|
||||||
|
return await db_events.location
|
||||||
|
.where('event_id')
|
||||||
|
.equals(current_event_id)
|
||||||
|
.sortBy('name');
|
||||||
|
})
|
||||||
|
);
|
||||||
|
// { event_location_id: location_name } — consumed by Element_ae_obj_field_editor select
|
||||||
|
let location_select_options = $derived(
|
||||||
|
Object.fromEntries(
|
||||||
|
($lq__event_location_obj_li ?? []).map((loc) => [
|
||||||
|
(loc as { event_location_id: string }).event_location_id,
|
||||||
|
(loc as { name: string }).name
|
||||||
|
])
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
// QR Code Generation Logic
|
// QR Code Generation Logic
|
||||||
$events_sess.pres_mgmt.session__updated_on = null;
|
$events_sess.pres_mgmt.session__updated_on = null;
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
@@ -177,7 +202,33 @@ $effect(() => {
|
|||||||
$events_loc.pres_mgmt.time_format
|
$events_loc.pres_mgmt.time_format
|
||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
{#if $lq__event_session_obj.event_location_name}
|
|
||||||
|
<!-- Room/Location: editable in edit_mode via select from this event's locations.
|
||||||
|
WHY: event_location_id is a FK — staff need to pick from known rooms,
|
||||||
|
not type a raw UUID. The liveQuery above loads locations for this event. -->
|
||||||
|
{#if $ae_loc.edit_mode}
|
||||||
|
<Element_ae_obj_field_editor
|
||||||
|
display_block={true}
|
||||||
|
object_type="event_session"
|
||||||
|
object_id={$lq__event_session_obj.id}
|
||||||
|
field_name="event_location_id"
|
||||||
|
field_type="select"
|
||||||
|
edit_label="Room / Location"
|
||||||
|
current_value={$lq__event_session_obj.event_location_id ?? null}
|
||||||
|
allow_null={true}
|
||||||
|
select_options={location_select_options}
|
||||||
|
on_success={() =>
|
||||||
|
events_func.load_ae_obj_id__event_session({
|
||||||
|
api_cfg: $ae_api,
|
||||||
|
event_session_id: $lq__event_session_obj.id
|
||||||
|
})}>
|
||||||
|
<span
|
||||||
|
class="bg-tertiary-500/10 text-tertiary-700 dark:text-tertiary-300 inline-flex items-center gap-1.5 rounded-full px-3 py-1 text-sm font-semibold transition-colors duration-200">
|
||||||
|
<MapPin size="1em" class="text-xs" />
|
||||||
|
{$lq__event_session_obj.event_location_name ?? 'No room assigned'}
|
||||||
|
</span>
|
||||||
|
</Element_ae_obj_field_editor>
|
||||||
|
{:else if $lq__event_session_obj.event_location_name}
|
||||||
<span
|
<span
|
||||||
class="bg-tertiary-500/10 text-tertiary-700 dark:text-tertiary-300 inline-flex items-center gap-1.5 rounded-full px-3 py-1 text-sm font-semibold transition-colors duration-200">
|
class="bg-tertiary-500/10 text-tertiary-700 dark:text-tertiary-300 inline-flex items-center gap-1.5 rounded-full px-3 py-1 text-sm font-semibold transition-colors duration-200">
|
||||||
<MapPin size="1em" class="text-xs" />
|
<MapPin size="1em" class="text-xs" />
|
||||||
@@ -228,32 +279,55 @@ $effect(() => {
|
|||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Description: shown only when present. Collapsed by default (can be long). -->
|
<!-- Description: collapsed by default in view mode (can be long).
|
||||||
{#if $lq__event_session_obj?.description}
|
In edit mode, show the editor directly — no collapse needed when staff are updating it. -->
|
||||||
|
{#if $lq__event_session_obj?.description || $ae_loc.edit_mode}
|
||||||
<div
|
<div
|
||||||
class="border-surface-200-800 bg-surface-50-900 rounded-lg border px-4 py-3">
|
class="border-surface-200-800 bg-surface-50-900 rounded-lg border px-4 py-3">
|
||||||
<button
|
{#if $ae_loc.edit_mode}
|
||||||
type="button"
|
<Element_ae_obj_field_editor
|
||||||
class="focus-visible:ring-primary-500 flex w-full items-center justify-between gap-2 rounded text-left focus-visible:ring-2"
|
display_block={true}
|
||||||
onclick={() => (desc_expanded = !desc_expanded)}
|
object_type="event_session"
|
||||||
aria-expanded={desc_expanded}>
|
object_id={$lq__event_session_obj?.id}
|
||||||
<span
|
field_name="description"
|
||||||
class="text-xs font-bold tracking-wide uppercase opacity-40"
|
field_type="textarea"
|
||||||
>Description</span>
|
edit_label="Description"
|
||||||
<span class="shrink-0 text-xs opacity-40">
|
current_value={$lq__event_session_obj?.description ?? ''}
|
||||||
{#if desc_expanded}
|
placeholder="Session description..."
|
||||||
<ChevronUp size="1em" />
|
textarea_rows={4}
|
||||||
<span class="sr-only">Collapse description</span>
|
on_success={() =>
|
||||||
{:else}
|
events_func.load_ae_obj_id__event_session({
|
||||||
<ChevronDown size="1em" />
|
api_cfg: $ae_api,
|
||||||
<span class="sr-only">Expand description</span>
|
event_session_id: $lq__event_session_obj?.id
|
||||||
{/if}
|
})}>
|
||||||
</span>
|
<span class="text-xs font-bold tracking-wide uppercase opacity-40">
|
||||||
</button>
|
Description
|
||||||
{#if desc_expanded}
|
</span>
|
||||||
<p class="mt-2 text-sm leading-relaxed whitespace-pre-wrap">
|
</Element_ae_obj_field_editor>
|
||||||
{$lq__event_session_obj.description}
|
{:else}
|
||||||
</p>
|
<button
|
||||||
|
type="button"
|
||||||
|
class="focus-visible:ring-primary-500 flex w-full items-center justify-between gap-2 rounded text-left focus-visible:ring-2"
|
||||||
|
onclick={() => (desc_expanded = !desc_expanded)}
|
||||||
|
aria-expanded={desc_expanded}>
|
||||||
|
<span
|
||||||
|
class="text-xs font-bold tracking-wide uppercase opacity-40"
|
||||||
|
>Description</span>
|
||||||
|
<span class="shrink-0 text-xs opacity-40">
|
||||||
|
{#if desc_expanded}
|
||||||
|
<ChevronUp size="1em" />
|
||||||
|
<span class="sr-only">Collapse description</span>
|
||||||
|
{:else}
|
||||||
|
<ChevronDown size="1em" />
|
||||||
|
<span class="sr-only">Expand description</span>
|
||||||
|
{/if}
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
{#if desc_expanded}
|
||||||
|
<p class="mt-2 text-sm leading-relaxed whitespace-pre-wrap">
|
||||||
|
{$lq__event_session_obj?.description}
|
||||||
|
</p>
|
||||||
|
{/if}
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
Reference in New Issue
Block a user