feat(pres_mgmt): extract session search component + time window filter
- Extract session search form into ae_comp__pres_mgmt_session_search.svelte (parallels ae_comp__badge_search.svelte); removes ~145 lines from +page.svelte - Add time window filter: Clock icon toggle button reveals compact before/after selects; trusted users get 3d/7d options; active state highlighted in amber - Add passes_hide_filter to IDB fast path to mirror API qry_hidden logic and eliminate the hidden-session blink on revalidation - Add passes_time_window applied to both IDB fast path and API results - Add time window state fields to PresMgmtLocState + pres_mgmt_loc_defaults - Add contextual warning in "No sessions found" when time filter is active - badges: hide "Start Here" button for trusted_access users; tweak button shade - badges: scope placeholder CSS fix to input only (not textarea) - Add MODULE__AE_Events_PressMgmt_Launcher.md doc Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -106,6 +106,11 @@ export interface PresMgmtLocState {
|
||||
location_name_qry_str: string | null; // persisted location filter text
|
||||
refresh_interval: number; // auto-refresh interval in seconds (0 = disabled)
|
||||
|
||||
// --- Time window filter (onsite use: show only sessions near current time) ---
|
||||
enable_time_window: boolean; // false = off (show all); true = apply window
|
||||
time_window_before_minutes: number; // include sessions that started up to N min ago
|
||||
time_window_after_minutes: number; // include sessions starting within next N min
|
||||
|
||||
// --- Report display preferences (user-controlled, persisted) ---
|
||||
rpt__session_no_files: boolean; // show "sessions with no files" report section
|
||||
rpt__session_poc_agree: boolean; // show "session POC agreement" report section
|
||||
@@ -282,6 +287,11 @@ export const pres_mgmt_loc_defaults: PresMgmtLocState = {
|
||||
location_name_qry_str: null,
|
||||
refresh_interval: 0,
|
||||
|
||||
// Time window filter
|
||||
enable_time_window: false,
|
||||
time_window_before_minutes: 30,
|
||||
time_window_after_minutes: 720,
|
||||
|
||||
// Report display preferences
|
||||
rpt__session_no_files: true,
|
||||
rpt__session_poc_agree: false,
|
||||
|
||||
@@ -313,13 +313,15 @@ let step_label = $derived(
|
||||
/* Placeholder text must read as a hint, not as filled content.
|
||||
Tailwind v4 sets placeholder color too dark on light backgrounds.
|
||||
Same fix as ae_comp__badge_print_controls.svelte. */
|
||||
form input::placeholder,
|
||||
form textarea::placeholder {
|
||||
|
||||
/* form textarea::placeholder */
|
||||
form input::placeholder {
|
||||
color: #9ca3af; /* gray-400 */
|
||||
opacity: 1; /* Firefox: override default 0.54 opacity */
|
||||
}
|
||||
:global(.dark) form input::placeholder,
|
||||
:global(.dark) form textarea::placeholder {
|
||||
|
||||
/* :global(.dark) form textarea::placeholder */
|
||||
:global(.dark) form input::placeholder {
|
||||
color: #6b7280; /* gray-500 in dark mode */
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -177,8 +177,9 @@ function handle_qr_scan_result(event: {
|
||||
onclick={() => document.getElementById('badge_fulltext_search_qry_str')?.focus()}
|
||||
aria-label="Start here — focus search field"
|
||||
data-testid="badge-start-btn"
|
||||
class="btn btn-sm preset-filled-secondary-300-700 font-semibold"
|
||||
class="btn btn-sm preset-filled-secondary-200-800 font-semibold"
|
||||
class:opacity-30={!!badges_loc.current.fulltext_search_qry_str}
|
||||
class:hidden={$ae_loc.trusted_access}
|
||||
>
|
||||
<StepForward size="1em" class="mx-1" />
|
||||
Start Here
|
||||
|
||||
@@ -46,12 +46,11 @@ import {
|
||||
ListChecks,
|
||||
LoaderCircle,
|
||||
Mails,
|
||||
MapPin,
|
||||
RemoveFormatting,
|
||||
Search,
|
||||
TriangleAlert,
|
||||
Upload
|
||||
} from '@lucide/svelte';
|
||||
import Comp_pres_mgmt_session_search from './ae_comp__pres_mgmt_session_search.svelte';
|
||||
// Quickly save the data passed from the parent(s) to the Svelte stores, localStorage, and other.
|
||||
// NOTE: Derived from data.account_id (prop) instead of $slct.account_id (store)
|
||||
// to prevent circular dependency loops during hydration.
|
||||
@@ -156,7 +155,11 @@ let search_params = $derived({
|
||||
.trim(),
|
||||
location: pres_mgmt_loc.current.location_name_qry_str,
|
||||
event_id: $events_slct?.event_id,
|
||||
remote_first: pres_mgmt_loc.current.qry__remote_first
|
||||
remote_first: pres_mgmt_loc.current.qry__remote_first,
|
||||
qry_hidden: pres_mgmt_loc.current.qry_hidden,
|
||||
enable_time_window: pres_mgmt_loc.current.enable_time_window,
|
||||
time_window_before_minutes: pres_mgmt_loc.current.time_window_before_minutes,
|
||||
time_window_after_minutes: pres_mgmt_loc.current.time_window_after_minutes
|
||||
});
|
||||
|
||||
$effect(() => {
|
||||
@@ -180,6 +183,35 @@ async function handle_search_refresh(params: any) {
|
||||
const event_id = params.event_id;
|
||||
const remote_first = params.remote_first;
|
||||
|
||||
// Snapshot filter params at search time — avoids stale reads across async boundaries.
|
||||
const { enable_time_window, time_window_before_minutes, time_window_after_minutes, qry_hidden } = params;
|
||||
|
||||
// Mirror the API's hide filter in the fast path so IDB results match what the
|
||||
// API will return. Without this, hidden sessions briefly appear for trusted users
|
||||
// before the API revalidation removes them (the blink).
|
||||
//
|
||||
// NOTE: only event_session.hide is checked here — NOT hide_event_launcher.
|
||||
// hide_event_launcher removes sessions from the Launcher only (used to drop past
|
||||
// blocks from the kiosk view). Those sessions remain fully accessible in pres_mgmt.
|
||||
function passes_hide_filter(session: { hide?: boolean | null }): boolean {
|
||||
if (qry_hidden === 'not_hidden') return !session.hide;
|
||||
if (qry_hidden === 'hidden') return !!session.hide;
|
||||
return true; // 'all'
|
||||
}
|
||||
|
||||
// Sessions with no start_datetime are always shown when the time filter is active
|
||||
// (e.g. unscheduled placeholder sessions at BGH).
|
||||
function passes_time_window(session: { start_datetime?: Date | string | null }): boolean {
|
||||
if (!enable_time_window) return true;
|
||||
if (!session.start_datetime) return true;
|
||||
const now = Date.now();
|
||||
const start = new Date(session.start_datetime).getTime();
|
||||
return (
|
||||
start >= now - time_window_before_minutes * 60_000 &&
|
||||
start <= now + time_window_after_minutes * 60_000
|
||||
);
|
||||
}
|
||||
|
||||
if (log_lvl)
|
||||
console.log(
|
||||
`[Session Search #${current_search_id}] Refreshing (remote=${remote_first}, event=${event_id}, str=${params.str})...`
|
||||
@@ -200,6 +232,9 @@ async function handle_search_refresh(params: any) {
|
||||
.where('event_id')
|
||||
.equals(event_id)
|
||||
.filter((session) => {
|
||||
if (!passes_hide_filter(session)) return false;
|
||||
if (!passes_time_window(session)) return false;
|
||||
|
||||
if (
|
||||
location_name &&
|
||||
session.event_location_name !== location_name
|
||||
@@ -276,6 +311,7 @@ async function handle_search_refresh(params: any) {
|
||||
|
||||
// Client-side Filter Guard: Ensure API results match local criteria (Backup filter)
|
||||
api_results = api_results.filter((session) => {
|
||||
if (!passes_time_window(session)) return false;
|
||||
if (
|
||||
location_name &&
|
||||
session.event_location_name !== location_name
|
||||
@@ -339,16 +375,6 @@ if (
|
||||
pres_mgmt_loc.current.saved_search__session_location_name;
|
||||
}
|
||||
|
||||
function handle_search_trigger() {
|
||||
pres_mgmt_loc.current.search_version++;
|
||||
}
|
||||
|
||||
function prevent_default<T extends Event>(fn: (event: T) => void) {
|
||||
return function (event: T) {
|
||||
event.preventDefault();
|
||||
fn(event);
|
||||
};
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
@@ -422,97 +448,8 @@ function prevent_default<T extends Event>(fn: (event: T) => void) {
|
||||
</header>
|
||||
|
||||
{#if !pres_mgmt_loc.current.show_content__event_view || pres_mgmt_loc.current.show_content__event_view == 'default'}
|
||||
<div class="preset-tonal-primary rounded-xl">
|
||||
<form
|
||||
onsubmit={prevent_default(() => handle_search_trigger())}
|
||||
autocomplete="off"
|
||||
class="form flex w-full grow flex-row flex-wrap items-center justify-center gap-1">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-sm ae_btn_warning mx-1"
|
||||
class:hidden={!$ae_loc.authenticated_access}
|
||||
onclick={() => {
|
||||
pres_mgmt_loc.current.location_name_qry_str = '';
|
||||
pres_mgmt_loc.current.show_content__session_search_room_name =
|
||||
!pres_mgmt_loc.current.show_content__session_search_room_name;
|
||||
handle_search_trigger();
|
||||
}}
|
||||
title="Search by location name">
|
||||
<MapPin size="1em" />
|
||||
</button>
|
||||
|
||||
<select
|
||||
name="location_name_list"
|
||||
id="session_location_name_list"
|
||||
bind:value={pres_mgmt_loc.current.location_name_qry_str}
|
||||
class="input mx-1 w-min max-w-40 min-w-fit font-mono text-xs font-bold transition-all"
|
||||
class:hidden={!$ae_loc.authenticated_access ||
|
||||
!pres_mgmt_loc.current.show_content__session_search_room_name}
|
||||
onchange={() => handle_search_trigger()}
|
||||
title="Select to filter based on the location/room name">
|
||||
{#if $lq__event_location_obj_li}
|
||||
<option value="">Location / Room</option>
|
||||
{#each $lq__event_location_obj_li as event_location_obj (event_location_obj.event_location_id)}
|
||||
<option value={event_location_obj?.name}
|
||||
>{event_location_obj.name}</option>
|
||||
{/each}
|
||||
{/if}
|
||||
</select>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
onclick={() => {
|
||||
pres_mgmt_loc.current.fulltext_search_qry_str = '';
|
||||
handle_search_trigger();
|
||||
}}
|
||||
class:hidden={!pres_mgmt_loc.current.fulltext_search_qry_str}
|
||||
class="btn btn-sm ae_btn_warning mx-1"
|
||||
title="Clear search text">
|
||||
<RemoveFormatting size="1em" />
|
||||
</button>
|
||||
|
||||
<!-- svelte-ignore a11y_autofocus -->
|
||||
<input
|
||||
type="search"
|
||||
placeholder="Search for a session"
|
||||
id="session_fulltext_search_qry_str"
|
||||
bind:value={pres_mgmt_loc.current.fulltext_search_qry_str}
|
||||
class="input text-1xl ae_btn_info mx-1 w-80 font-mono font-bold transition-all hover:text-2xl"
|
||||
onkeyup={(e) => {
|
||||
if (e.key === 'Enter') handle_search_trigger();
|
||||
}}
|
||||
autofocus
|
||||
data-ignore="true" />
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
class="btn btn-lg ae_btn_primary mx-1 w-48 text-2xl font-bold"
|
||||
title="Search for a session">
|
||||
{#if $events_sess.pres_mgmt.status_qry__search == 'loading'}
|
||||
<LoaderCircle
|
||||
size="1em"
|
||||
class="text-success-800-200 mx-1 animate-spin" />
|
||||
{:else}
|
||||
<Search size="1em" class="mx-1 text-neutral-800/80" />
|
||||
{/if}
|
||||
Search
|
||||
</button>
|
||||
|
||||
{#if $ae_loc.edit_mode}
|
||||
<label
|
||||
class="bg-surface-200-800 rounded-token flex cursor-pointer items-center gap-1 px-2 py-1 text-xs font-semibold opacity-70 transition-all hover:opacity-100">
|
||||
<span> Remote First </span>
|
||||
<input
|
||||
type="checkbox"
|
||||
bind:checked={
|
||||
pres_mgmt_loc.current.qry__remote_first
|
||||
}
|
||||
onchange={() => handle_search_trigger()}
|
||||
class="checkbox checkbox-sm" />
|
||||
</label>
|
||||
{/if}
|
||||
</form>
|
||||
</div>
|
||||
<Comp_pres_mgmt_session_search
|
||||
event_location_obj_li={$lq__event_location_obj_li} />
|
||||
|
||||
{#if event_session_id_li.length}
|
||||
<Comp_event_session_obj_li_wrapper
|
||||
@@ -541,6 +478,15 @@ function prevent_default<T extends Event>(fn: (event: T) => void) {
|
||||
Use the search bar above to find your session.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{#if pres_mgmt_loc.current.enable_time_window}
|
||||
<!-- Time filter is ON — most common cause of "no results" when
|
||||
sessions exist but are scheduled outside the current window. -->
|
||||
<div class="preset-tonal-error rounded-lg p-3 text-center text-sm font-semibold">
|
||||
⏰ Time filter is ON — sessions outside the current window are hidden.
|
||||
Disable the clock button in the search bar to see all sessions.
|
||||
</div>
|
||||
{/if}
|
||||
<div class="bg-surface-50-900/60 rounded-lg p-3">
|
||||
<span
|
||||
class="mb-2 block text-xs font-bold tracking-wide uppercase opacity-50"
|
||||
|
||||
@@ -0,0 +1,243 @@
|
||||
<script lang="ts">
|
||||
interface Props {
|
||||
event_location_obj_li: any[] | undefined;
|
||||
log_lvl?: number;
|
||||
}
|
||||
|
||||
let { event_location_obj_li, log_lvl = 0 }: Props = $props();
|
||||
|
||||
import { Clock, LoaderCircle, MapPin, RemoveFormatting, Search } from '@lucide/svelte';
|
||||
import { ae_loc } from '$lib/stores/ae_stores';
|
||||
import { events_sess } from '$lib/stores/ae_events_stores';
|
||||
import { pres_mgmt_loc } from '$lib/stores/ae_events_stores__pres_mgmt.svelte';
|
||||
|
||||
function handle_search_trigger() {
|
||||
pres_mgmt_loc.current.search_version++;
|
||||
}
|
||||
|
||||
function prevent_default<T extends Event>(fn: (event: T) => void) {
|
||||
return function (event: T) {
|
||||
event.preventDefault();
|
||||
fn(event);
|
||||
};
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="ae_group pres_mgmt_session_search preset-tonal-primary rounded-xl">
|
||||
<form
|
||||
onsubmit={prevent_default(() => handle_search_trigger())}
|
||||
autocomplete="off"
|
||||
class="form flex w-full grow flex-row flex-wrap items-center justify-center gap-1 px-2 py-2">
|
||||
|
||||
<!-- {#if $ae_loc.edit_mode} -->
|
||||
|
||||
<!-- Location filter toggle + select (authenticated users only) -->
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-sm mx-1"
|
||||
class:hidden={!$ae_loc.authenticated_access}
|
||||
class:opacity-10={pres_mgmt_loc.current.show_content__session_search_room_name}
|
||||
class:preset-filled-primary-300-700={pres_mgmt_loc.current.show_content__session_search_room_name}
|
||||
class:preset-filled-primary-100-900={!pres_mgmt_loc.current.show_content__session_search_room_name}
|
||||
onclick={() => {
|
||||
pres_mgmt_loc.current.location_name_qry_str = '';
|
||||
pres_mgmt_loc.current.show_content__session_search_room_name =
|
||||
!pres_mgmt_loc.current.show_content__session_search_room_name;
|
||||
handle_search_trigger();
|
||||
}}
|
||||
title="Filter by room / location">
|
||||
<MapPin size="1em" />
|
||||
</button>
|
||||
|
||||
|
||||
|
||||
<!-- Time window toggle icon button (authenticated only).
|
||||
Highlighted when active so onsite staff can see at a glance whether the
|
||||
filter is on. The controls below only appear when enabled. -->
|
||||
|
||||
<!-- TEMP: hide clock button for now, even in edit mode, since time filtering is a bit niche and the controls are a bit complex for non-technical users. Can re-enable when we have a better UI for the time filter controls. -->
|
||||
<button
|
||||
type="button"
|
||||
onclick={() => {
|
||||
pres_mgmt_loc.current.enable_time_window =
|
||||
!pres_mgmt_loc.current.enable_time_window;
|
||||
handle_search_trigger();
|
||||
}}
|
||||
title={pres_mgmt_loc.current.enable_time_window
|
||||
? 'Time filter ON — click to disable'
|
||||
: 'Show only sessions near current time'}
|
||||
class="btn btn-sm mx-1"
|
||||
class:hidden={!$ae_loc.edit_mode && 1==3}
|
||||
class:opacity-10={pres_mgmt_loc.current.enable_time_window}
|
||||
class:preset-filled-primary-300-700={pres_mgmt_loc.current.enable_time_window}
|
||||
class:preset-filled-primary-100-900={!pres_mgmt_loc.current.enable_time_window}>
|
||||
<Clock size="1em" />
|
||||
</button>
|
||||
|
||||
<!-- {/if} -->
|
||||
|
||||
<!-- Main search input -->
|
||||
<!-- svelte-ignore a11y_autofocus -->
|
||||
<input
|
||||
type="search"
|
||||
autofocus
|
||||
placeholder="Search for a session"
|
||||
id="session_fulltext_search_qry_str"
|
||||
bind:value={pres_mgmt_loc.current.fulltext_search_qry_str}
|
||||
autocomplete="off"
|
||||
data-ignore="true"
|
||||
class="input text-1xl ae_btn_info mx-1 w-80 font-mono font-bold transition-all hover:text-2xl"
|
||||
onkeyup={(e) => {
|
||||
if (e.key === 'Enter') handle_search_trigger();
|
||||
}}
|
||||
title="Search sessions by title, description, speaker, etc."
|
||||
/>
|
||||
|
||||
<!-- Search submit button -->
|
||||
<button
|
||||
type="submit"
|
||||
class="btn btn-lg ae_btn_primary mx-1 w-48 text-2xl font-bold"
|
||||
title="Search for a session">
|
||||
{#if $events_sess.pres_mgmt.status_qry__search == 'loading'}
|
||||
<LoaderCircle size="1em" class="text-success-800-200 mx-1 animate-spin" />
|
||||
{:else}
|
||||
<Search size="1em" class="mx-1 text-neutral-800/80" />
|
||||
{/if}
|
||||
Search
|
||||
</button>
|
||||
|
||||
<!-- Clear search text button -->
|
||||
<button
|
||||
type="button"
|
||||
onclick={() => {
|
||||
pres_mgmt_loc.current.fulltext_search_qry_str = '';
|
||||
handle_search_trigger();
|
||||
}}
|
||||
class:hidden={!pres_mgmt_loc.current.fulltext_search_qry_str}
|
||||
class="btn btn-sm ae_btn_warning mx-1"
|
||||
title="Clear search text">
|
||||
<RemoveFormatting size="1em" />
|
||||
</button>
|
||||
|
||||
|
||||
<!-- Remote First (edit_mode only) -->
|
||||
{#if $ae_loc.edit_mode}
|
||||
<label
|
||||
class="bg-surface-200-800 rounded-token flex cursor-pointer items-center gap-1 px-2 py-1 text-xs font-semibold opacity-70 transition-all hover:opacity-100">
|
||||
<span> Remote First </span>
|
||||
<input
|
||||
type="checkbox"
|
||||
bind:checked={pres_mgmt_loc.current.qry__remote_first}
|
||||
onchange={() => handle_search_trigger()}
|
||||
class="checkbox checkbox-sm" />
|
||||
</label>
|
||||
{/if}
|
||||
|
||||
{#if pres_mgmt_loc.current.enable_time_window ||
|
||||
pres_mgmt_loc.current.show_content__session_search_room_name}
|
||||
|
||||
<div class="w-full flex flex-wrap items-center justify-center gap-2 px-2 pb-2 text-xs">
|
||||
|
||||
<span class="flex flex-wrap items-center justify-center gap-2 text-xs">
|
||||
<select
|
||||
name="location_name_list"
|
||||
id="session_location_name_list"
|
||||
bind:value={pres_mgmt_loc.current.location_name_qry_str}
|
||||
class="input mx-1 w-min max-w-40 min-w-fit font-mono text-xs font-bold transition-all"
|
||||
class:hidden={!$ae_loc.authenticated_access ||
|
||||
!pres_mgmt_loc.current.show_content__session_search_room_name}
|
||||
onchange={() => handle_search_trigger()}
|
||||
title="Filter by location / room name">
|
||||
{#if event_location_obj_li}
|
||||
<option value="">Location / Room</option>
|
||||
{#each event_location_obj_li as loc (loc.event_location_id)}
|
||||
<option value={loc?.name}>{loc.name}</option>
|
||||
{/each}
|
||||
{/if}
|
||||
</select>
|
||||
|
||||
<!-- Location filter toggle + select (authenticated users only) -->
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-sm mx-1"
|
||||
class:hidden={!pres_mgmt_loc.current.show_content__session_search_room_name}
|
||||
class:preset-filled-primary-300-700={pres_mgmt_loc.current.show_content__session_search_room_name}
|
||||
class:preset-filled-primary-100-900={!pres_mgmt_loc.current.show_content__session_search_room_name}
|
||||
onclick={() => {
|
||||
pres_mgmt_loc.current.location_name_qry_str = '';
|
||||
pres_mgmt_loc.current.show_content__session_search_room_name =
|
||||
!pres_mgmt_loc.current.show_content__session_search_room_name;
|
||||
handle_search_trigger();
|
||||
}}
|
||||
title="Filter by room / location">
|
||||
<MapPin size="1em" />
|
||||
</button>
|
||||
</span>
|
||||
|
||||
<!-- Time window controls — compact row, shown only when filter is active.
|
||||
Two simple selects (before / after current time) keep this readable for
|
||||
all experience levels without the noise of preset chip arrays. -->
|
||||
{#if pres_mgmt_loc.current.enable_time_window}
|
||||
<div
|
||||
class="flex flex-wrap items-center justify-center gap-2 text-xs">
|
||||
<Clock size="0.875em" class="opacity-50" />
|
||||
<span class="font-semibold opacity-70">Showing sessions:</span>
|
||||
<span class="opacity-50">−</span>
|
||||
<select
|
||||
bind:value={pres_mgmt_loc.current.time_window_before_minutes}
|
||||
onchange={handle_search_trigger}
|
||||
class="select select-sm max-w-fit px-1 text-xs">
|
||||
<option value={0}>0m</option>
|
||||
<option value={25}>25m</option>
|
||||
<option value={90}>90m</option>
|
||||
<option value={120}>2h</option>
|
||||
<option value={240}>4h</option>
|
||||
<option value={480}>8h</option>
|
||||
<option value={720}>12h</option>
|
||||
<option value={1440}>24h</option>
|
||||
{#if $ae_loc.trusted_access}<option value={4320}>3d</option>{/if}
|
||||
{#if $ae_loc.trusted_access}<option value={10080}>7d</option>{/if}
|
||||
</select>
|
||||
<span class="opacity-40">to</span>
|
||||
<span class="opacity-50">+</span>
|
||||
<select
|
||||
bind:value={pres_mgmt_loc.current.time_window_after_minutes}
|
||||
onchange={handle_search_trigger}
|
||||
class="select select-sm max-w-fit px-1 text-xs">
|
||||
<option value={90}>90m</option>
|
||||
<option value={120}>2h</option>
|
||||
<option value={240}>4h</option>
|
||||
<option value={480}>8h</option>
|
||||
<option value={720}>12h</option>
|
||||
<option value={1440}>24h</option>
|
||||
{#if $ae_loc.trusted_access}<option value={4320}>3d</option>{/if}
|
||||
{#if $ae_loc.trusted_access}<option value={10080}>7d</option>{/if}
|
||||
</select>
|
||||
<span class="opacity-40">from now</span>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
onclick={() => {
|
||||
pres_mgmt_loc.current.enable_time_window =
|
||||
!pres_mgmt_loc.current.enable_time_window;
|
||||
handle_search_trigger();
|
||||
}}
|
||||
title={pres_mgmt_loc.current.enable_time_window
|
||||
? 'Time filter ON — click to disable'
|
||||
: 'Show only sessions near current time'}
|
||||
class="btn btn-sm mx-1"
|
||||
class:hidden={!pres_mgmt_loc.current.enable_time_window}
|
||||
class:preset-filled-primary-300-700={pres_mgmt_loc.current.enable_time_window}
|
||||
class:preset-filled-primary-100-900={!pres_mgmt_loc.current.enable_time_window}>
|
||||
<Clock size="1em" />
|
||||
</button>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
</div>
|
||||
|
||||
{/if}
|
||||
|
||||
|
||||
</form>
|
||||
</div>
|
||||
Reference in New Issue
Block a user