Badges: auto-focus input when field accordion opens; add Revert button to field forms
This commit is contained in:
@@ -22,7 +22,7 @@
|
|||||||
import { ae_api, ae_loc } from '$lib/stores/ae_stores';
|
import { ae_api, ae_loc } from '$lib/stores/ae_stores';
|
||||||
import { events_func } from '$lib/ae_events_functions';
|
import { events_func } from '$lib/ae_events_functions';
|
||||||
import { browser } from '$app/environment';
|
import { browser } from '$app/environment';
|
||||||
import { Pencil, Check, X, LoaderCircle, ChevronDown, Printer } from 'lucide-svelte';
|
import { Pencil, Check, X, LoaderCircle, ChevronDown, Printer, RotateCcw } from 'lucide-svelte';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
event_id: string;
|
event_id: string;
|
||||||
@@ -283,6 +283,33 @@
|
|||||||
?? $lq__event_badge_obj?.badge_type_code
|
?? $lq__event_badge_obj?.badge_type_code
|
||||||
?? ''
|
?? ''
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// --- Focus management: focus the input when its accordion opens ---
|
||||||
|
// rAF gives the CSS accordion one repaint tick before focus() is called,
|
||||||
|
// avoiding jumping to an invisible (height: 0) element.
|
||||||
|
let input_ref_name: HTMLInputElement | undefined;
|
||||||
|
let input_ref_title: HTMLInputElement | undefined;
|
||||||
|
let input_ref_affiliations: HTMLTextAreaElement | undefined;
|
||||||
|
let input_ref_location: HTMLInputElement | undefined;
|
||||||
|
let input_ref_pronouns: HTMLInputElement | undefined;
|
||||||
|
let input_ref_allow_tracking: HTMLInputElement | undefined;
|
||||||
|
let select_ref_badge_type: HTMLSelectElement | undefined;
|
||||||
|
|
||||||
|
$effect(() => {
|
||||||
|
const field = active_field;
|
||||||
|
if (!field) return;
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
switch (field) {
|
||||||
|
case 'name': input_ref_name?.focus(); break;
|
||||||
|
case 'title': input_ref_title?.focus(); break;
|
||||||
|
case 'affiliations': input_ref_affiliations?.focus(); break;
|
||||||
|
case 'location': input_ref_location?.focus(); break;
|
||||||
|
case 'pronouns': input_ref_pronouns?.focus(); break;
|
||||||
|
case 'allow_tracking': input_ref_allow_tracking?.focus(); break;
|
||||||
|
case 'badge_type': select_ref_badge_type?.focus(); break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- ============================================================
|
<!-- ============================================================
|
||||||
@@ -332,9 +359,21 @@
|
|||||||
</div>
|
</div>
|
||||||
{/snippet}
|
{/snippet}
|
||||||
|
|
||||||
<!-- Save/cancel row (inside accordion edit forms) -->
|
<!-- Save/cancel row (inside accordion edit forms).
|
||||||
{#snippet field_actions(field_key: string, on_save: () => void, on_cancel: () => void)}
|
on_revert is optional — only passed when an override is currently saved;
|
||||||
|
clears the override back to the base imported value. Layout: [Revert] [Save] [X] -->
|
||||||
|
{#snippet field_actions(field_key: string, on_save: () => void, on_cancel: () => void, on_revert?: () => void)}
|
||||||
<div class="flex gap-2 mt-2">
|
<div class="flex gap-2 mt-2">
|
||||||
|
{#if on_revert}
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="btn btn-sm preset-tonal-warning shrink-0"
|
||||||
|
onclick={on_revert}
|
||||||
|
disabled={field_save_status[field_key] === 'saving'}
|
||||||
|
title="Remove override — restore original imported value"
|
||||||
|
aria-label="Revert to original value"
|
||||||
|
><RotateCcw size="13" /></button>
|
||||||
|
{/if}
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
class="btn btn-sm flex-1"
|
class="btn btn-sm flex-1"
|
||||||
@@ -453,13 +492,17 @@
|
|||||||
name="ctrl-full-name"
|
name="ctrl-full-name"
|
||||||
type="text"
|
type="text"
|
||||||
class="input w-full"
|
class="input w-full"
|
||||||
|
bind:this={input_ref_name}
|
||||||
bind:value={edit_full_name_override}
|
bind:value={edit_full_name_override}
|
||||||
placeholder={$lq__event_badge_obj?.full_name ?? 'Full name'}
|
placeholder={$lq__event_badge_obj?.full_name ?? 'Full name'}
|
||||||
/>
|
/>
|
||||||
{@render field_actions(
|
{@render field_actions(
|
||||||
'name',
|
'name',
|
||||||
() => save_field('name', { full_name_override: edit_full_name_override || null }),
|
() => save_field('name', { full_name_override: edit_full_name_override || null }),
|
||||||
() => cancel_field('name')
|
() => cancel_field('name'),
|
||||||
|
$lq__event_badge_obj?.full_name_override
|
||||||
|
? () => save_field('name', { full_name_override: null })
|
||||||
|
: undefined
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -501,13 +544,17 @@
|
|||||||
name="ctrl-pro-title"
|
name="ctrl-pro-title"
|
||||||
type="text"
|
type="text"
|
||||||
class="input w-full"
|
class="input w-full"
|
||||||
|
bind:this={input_ref_title}
|
||||||
bind:value={edit_professional_title_override}
|
bind:value={edit_professional_title_override}
|
||||||
placeholder={$lq__event_badge_obj?.professional_title ?? 'Professional title'}
|
placeholder={$lq__event_badge_obj?.professional_title ?? 'Professional title'}
|
||||||
/>
|
/>
|
||||||
{@render field_actions(
|
{@render field_actions(
|
||||||
'title',
|
'title',
|
||||||
() => save_field('title', { professional_title_override: edit_professional_title_override || null }),
|
() => save_field('title', { professional_title_override: edit_professional_title_override || null }),
|
||||||
() => cancel_field('title')
|
() => cancel_field('title'),
|
||||||
|
$lq__event_badge_obj?.professional_title_override
|
||||||
|
? () => save_field('title', { professional_title_override: null })
|
||||||
|
: undefined
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -549,13 +596,17 @@
|
|||||||
name="ctrl-affiliations"
|
name="ctrl-affiliations"
|
||||||
class="textarea w-full"
|
class="textarea w-full"
|
||||||
rows="2"
|
rows="2"
|
||||||
|
bind:this={input_ref_affiliations}
|
||||||
bind:value={edit_affiliations_override}
|
bind:value={edit_affiliations_override}
|
||||||
placeholder={$lq__event_badge_obj?.affiliations ?? 'Organization / affiliations'}
|
placeholder={$lq__event_badge_obj?.affiliations ?? 'Organization / affiliations'}
|
||||||
></textarea>
|
></textarea>
|
||||||
{@render field_actions(
|
{@render field_actions(
|
||||||
'affiliations',
|
'affiliations',
|
||||||
() => save_field('affiliations', { affiliations_override: edit_affiliations_override || null }),
|
() => save_field('affiliations', { affiliations_override: edit_affiliations_override || null }),
|
||||||
() => cancel_field('affiliations')
|
() => cancel_field('affiliations'),
|
||||||
|
$lq__event_badge_obj?.affiliations_override
|
||||||
|
? () => save_field('affiliations', { affiliations_override: null })
|
||||||
|
: undefined
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -597,13 +648,17 @@
|
|||||||
name="ctrl-location"
|
name="ctrl-location"
|
||||||
type="text"
|
type="text"
|
||||||
class="input w-full"
|
class="input w-full"
|
||||||
|
bind:this={input_ref_location}
|
||||||
bind:value={edit_location_override}
|
bind:value={edit_location_override}
|
||||||
placeholder={$lq__event_badge_obj?.location ?? 'City, State / Country'}
|
placeholder={$lq__event_badge_obj?.location ?? 'City, State / Country'}
|
||||||
/>
|
/>
|
||||||
{@render field_actions(
|
{@render field_actions(
|
||||||
'location',
|
'location',
|
||||||
() => save_field('location', { location_override: edit_location_override || null }),
|
() => save_field('location', { location_override: edit_location_override || null }),
|
||||||
() => cancel_field('location')
|
() => cancel_field('location'),
|
||||||
|
$lq__event_badge_obj?.location_override
|
||||||
|
? () => save_field('location', { location_override: null })
|
||||||
|
: undefined
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -640,6 +695,7 @@
|
|||||||
name="ctrl-allow-tracking"
|
name="ctrl-allow-tracking"
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
class="checkbox"
|
class="checkbox"
|
||||||
|
bind:this={input_ref_allow_tracking}
|
||||||
bind:checked={edit_allow_tracking}
|
bind:checked={edit_allow_tracking}
|
||||||
/>
|
/>
|
||||||
<span class="text-xs">Allow exhibitor lead scanning</span>
|
<span class="text-xs">Allow exhibitor lead scanning</span>
|
||||||
@@ -685,13 +741,17 @@
|
|||||||
name="ctrl-pronouns"
|
name="ctrl-pronouns"
|
||||||
type="text"
|
type="text"
|
||||||
class="input w-full"
|
class="input w-full"
|
||||||
|
bind:this={input_ref_pronouns}
|
||||||
bind:value={edit_pronouns_override}
|
bind:value={edit_pronouns_override}
|
||||||
placeholder={$lq__event_badge_obj?.pronouns ?? 'e.g. they/them'}
|
placeholder={$lq__event_badge_obj?.pronouns ?? 'e.g. they/them'}
|
||||||
/>
|
/>
|
||||||
{@render field_actions(
|
{@render field_actions(
|
||||||
'pronouns',
|
'pronouns',
|
||||||
() => save_field('pronouns', { pronouns_override: edit_pronouns_override || null }),
|
() => save_field('pronouns', { pronouns_override: edit_pronouns_override || null }),
|
||||||
() => cancel_field('pronouns')
|
() => cancel_field('pronouns'),
|
||||||
|
$lq__event_badge_obj?.pronouns_override
|
||||||
|
? () => save_field('pronouns', { pronouns_override: null })
|
||||||
|
: undefined
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -739,6 +799,7 @@
|
|||||||
id="ctrl-badge-type"
|
id="ctrl-badge-type"
|
||||||
name="ctrl-badge-type"
|
name="ctrl-badge-type"
|
||||||
class="select w-full"
|
class="select w-full"
|
||||||
|
bind:this={select_ref_badge_type}
|
||||||
bind:value={edit_badge_type_code}
|
bind:value={edit_badge_type_code}
|
||||||
>
|
>
|
||||||
<option value={null}>— Select badge type —</option>
|
<option value={null}>— Select badge type —</option>
|
||||||
@@ -756,7 +817,10 @@
|
|||||||
? (badge_type_code_li.find(item => item.code === edit_badge_type_code)?.name ?? edit_badge_type_code)
|
? (badge_type_code_li.find(item => item.code === edit_badge_type_code)?.name ?? edit_badge_type_code)
|
||||||
: null
|
: null
|
||||||
}),
|
}),
|
||||||
() => cancel_field('badge_type')
|
() => cancel_field('badge_type'),
|
||||||
|
$lq__event_badge_obj?.badge_type_code_override
|
||||||
|
? () => save_field('badge_type', { badge_type_code_override: null, badge_type_override: null })
|
||||||
|
: undefined
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user