diff --git a/src/routes/events/[event_id]/(badges)/badges/[badge_id]/ae_comp__badge_print_controls.svelte b/src/routes/events/[event_id]/(badges)/badges/[badge_id]/ae_comp__badge_print_controls.svelte index fa653623..09cc71cf 100644 --- a/src/routes/events/[event_id]/(badges)/badges/[badge_id]/ae_comp__badge_print_controls.svelte +++ b/src/routes/events/[event_id]/(badges)/badges/[badge_id]/ae_comp__badge_print_controls.svelte @@ -311,6 +311,33 @@ }); }); + // --- Dirty detection: compare live edit value against the last-saved badge obj --- + // Save button is hidden when the value matches saved state (no unsaved change); + // shown with a warning/attention style the moment something changes. + // Using string comparison for text fields; boolean comparison for allow_tracking; + // null-safe equality for badge_type_code (null vs null must be equal). + let is_dirty_name = $derived( + edit_full_name_override !== ($lq__event_badge_obj?.full_name_override ?? $lq__event_badge_obj?.full_name ?? '') + ); + let is_dirty_title = $derived( + edit_professional_title_override !== ($lq__event_badge_obj?.professional_title_override ?? $lq__event_badge_obj?.professional_title ?? '') + ); + let is_dirty_affiliations = $derived( + edit_affiliations_override !== ($lq__event_badge_obj?.affiliations_override ?? $lq__event_badge_obj?.affiliations ?? '') + ); + let is_dirty_location = $derived( + edit_location_override !== ($lq__event_badge_obj?.location_override ?? $lq__event_badge_obj?.location ?? '') + ); + let is_dirty_pronouns = $derived( + edit_pronouns_override !== ($lq__event_badge_obj?.pronouns_override ?? $lq__event_badge_obj?.pronouns ?? '') + ); + let is_dirty_allow_tracking = $derived( + edit_allow_tracking !== ($lq__event_badge_obj?.allow_tracking ?? false) + ); + let is_dirty_badge_type = $derived( + edit_badge_type_code !== ($lq__event_badge_obj?.badge_type_code_override ?? $lq__event_badge_obj?.badge_type_code ?? null) + ); + // TC modal ref for the lead scanning terms & conditions dialog let tc_dialog_ref: HTMLDialogElement | undefined; @@ -371,41 +398,47 @@ {/snippet} -{#snippet field_actions(field_key: string, on_save: () => void, on_cancel: () => void, on_revert?: () => void)} + on_revert is optional — shown only when a saved override exists. + is_dirty: Save is hidden when clean (unchanged), warning-styled when dirty. + Layout when dirty: [Revert?] [⚠ Save] [X] / when clean: [Revert?] [X] --> +{#snippet field_actions(field_key: string, on_save: () => void, on_cancel: () => void, on_revert?: () => void, is_dirty = false)} + {@const status = field_save_status[field_key]} + {@const show_save = is_dirty || (status && status !== 'idle')}
{#if on_revert} {/if} - + {#if show_save} + + {/if}
@@ -565,7 +599,8 @@ () => cancel_field('title'), $lq__event_badge_obj?.professional_title_override ? () => save_field('title', { professional_title_override: null }) - : undefined + : undefined, + is_dirty_title )} @@ -617,7 +652,8 @@ () => cancel_field('affiliations'), $lq__event_badge_obj?.affiliations_override ? () => save_field('affiliations', { affiliations_override: null }) - : undefined + : undefined, + is_dirty_affiliations )} @@ -669,7 +705,8 @@ () => cancel_field('location'), $lq__event_badge_obj?.location_override ? () => save_field('location', { location_override: null }) - : undefined + : undefined, + is_dirty_location )} @@ -711,29 +748,33 @@ /> Allow exhibitor lead scanning - +
- + {#if is_dirty_allow_tracking || (field_save_status['allow_tracking'] && field_save_status['allow_tracking'] !== 'idle')} + + {/if}
@@ -864,7 +906,8 @@ () => 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 + : undefined, + is_dirty_badge_type )}