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',
|
||||
'code',
|
||||
'type_code',
|
||||
'event_location_id',
|
||||
'poc_agree',
|
||||
'poc_kv_json',
|
||||
'name',
|
||||
|
||||
@@ -17,6 +17,7 @@ let {
|
||||
|
||||
// Imports
|
||||
import { Modal } from 'flowbite-svelte';
|
||||
import { liveQuery } from 'dexie';
|
||||
import type { key_val } from '$lib/stores/ae_stores';
|
||||
import { ae_util } from '$lib/ae_utils/ae_utils';
|
||||
import Element_ae_obj_field_editor from '$lib/elements/element_ae_obj_field_editor.svelte';
|
||||
@@ -29,6 +30,7 @@ import {
|
||||
events_slct
|
||||
} from '$lib/stores/ae_events_stores';
|
||||
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_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)
|
||||
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
|
||||
$events_sess.pres_mgmt.session__updated_on = null;
|
||||
$effect(() => {
|
||||
@@ -177,7 +202,33 @@ $effect(() => {
|
||||
$events_loc.pres_mgmt.time_format
|
||||
)}
|
||||
</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
|
||||
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" />
|
||||
@@ -228,32 +279,55 @@ $effect(() => {
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<!-- Description: shown only when present. Collapsed by default (can be long). -->
|
||||
{#if $lq__event_session_obj?.description}
|
||||
<!-- Description: collapsed by default in view mode (can be long).
|
||||
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
|
||||
class="border-surface-200-800 bg-surface-50-900 rounded-lg border px-4 py-3">
|
||||
<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 $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="description"
|
||||
field_type="textarea"
|
||||
edit_label="Description"
|
||||
current_value={$lq__event_session_obj?.description ?? ''}
|
||||
placeholder="Session description..."
|
||||
textarea_rows={4}
|
||||
on_success={() =>
|
||||
events_func.load_ae_obj_id__event_session({
|
||||
api_cfg: $ae_api,
|
||||
event_session_id: $lq__event_session_obj?.id
|
||||
})}>
|
||||
<span class="text-xs font-bold tracking-wide uppercase opacity-40">
|
||||
Description
|
||||
</span>
|
||||
</Element_ae_obj_field_editor>
|
||||
{:else}
|
||||
<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}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
Reference in New Issue
Block a user