From 547470a13abc602c344bc3194989136f9a2c028e Mon Sep 17 00:00:00 2001 From: Diego Imbert Date: Fri, 6 Feb 2026 15:07:53 +0100 Subject: [PATCH] Ctrl A --- frontend/src/lib/components/RunsPage.svelte | 3 - .../src/lib/components/runs/RunsTable.svelte | 24 +++++--- frontend/src/lib/svelte5Utils.svelte.ts | 55 ++++++++----------- 3 files changed, 39 insertions(+), 43 deletions(-) diff --git a/frontend/src/lib/components/RunsPage.svelte b/frontend/src/lib/components/RunsPage.svelte index 5cd33f224e..8788116993 100644 --- a/frontend/src/lib/components/RunsPage.svelte +++ b/frontend/src/lib/components/RunsPage.svelte @@ -34,7 +34,6 @@ import { untrack } from 'svelte' import { page } from '$app/state' import RunOption from '$lib/components/runs/RunOption.svelte' - import { createBubbler } from 'svelte/legacy' import Select from '$lib/components/select/Select.svelte' import AnimatedPane from '$lib/components/splitPanes/AnimatedPane.svelte' import { useSearchParams } from '$lib/svelte5UtilsKit.svelte' @@ -78,7 +77,6 @@ let argError = $state('') let resultError = $state('') let filterTimeout: ReturnType | undefined = undefined - let selectedManualDate = $state(0) let autoRefresh: boolean = $state(getAutoRefresh()) let runDrawer: Drawer | undefined = $state(undefined) let lookback: number = $state(1) @@ -159,7 +157,6 @@ function reset() { filters.min_ts = null filters.max_ts = null - selectedManualDate = 0 selectedIds = [] filters.schedule_path = null batchReRunOptions = { flow: {}, script: {} } diff --git a/frontend/src/lib/components/runs/RunsTable.svelte b/frontend/src/lib/components/runs/RunsTable.svelte index 7000287160..84a6ad22fb 100644 --- a/frontend/src/lib/components/runs/RunsTable.svelte +++ b/frontend/src/lib/components/runs/RunsTable.svelte @@ -8,7 +8,7 @@ import Popover from '../Popover.svelte' import { workspaceStore } from '$lib/stores' import './runs-grid.css' - import { useKeyboardModifiers } from '$lib/svelte5Utils.svelte' + import { useKeyPressed } from '$lib/svelte5Utils.svelte' import { twMerge } from 'tailwind-merge' import RightClickPopover from '../RightClickPopover.svelte' @@ -24,7 +24,6 @@ // const loadMoreQuantity: number = 100 lastFetchWentToEnd?: boolean perPage?: number - allSelected?: boolean } let { @@ -36,11 +35,22 @@ selectedWorkspace = $bindable(undefined), activeLabel = null, lastFetchWentToEnd = false, - perPage = 1000, - allSelected = $bindable() + perPage = 1000 }: Props = $props() - const keyboardModifiers = useKeyboardModifiers() + const keysPressed = useKeyPressed(['Shift', 'Control', 'Meta', 'A'], { + onKeyDown(key, e) { + if (key === 'A' && (keysPressed.Control || keysPressed.Meta)) { + e.preventDefault() + e.stopPropagation() + selectedIds = flatJobs + ? flatJobs + .filter((jobOrDate) => jobOrDate.type === 'job') + .map((jobOrDate) => jobOrDate.job.id) + : [] + } + } + }) let rightClickPopover: RightClickPopover | undefined = $state(undefined) function getTime(job: Job): string | undefined { @@ -290,14 +300,14 @@ selected={jobOrDate.job.id !== '-' && selectedIds.includes(jobOrDate.job.id)} on:select={() => { const jobId = jobOrDate.job.id - if (keyboardModifiers.control || keyboardModifiers.meta) { + if (keysPressed.Control || keysPressed.Meta) { if (selectedIds.includes(jobOrDate.job.id)) { selectedIds = selectedIds.filter((id) => id != jobId) } else { selectedIds.push(jobId) selectedIds = selectedIds } - } else if (keyboardModifiers.shift && selectedIds.length > 0) { + } else if (keysPressed.Shift && selectedIds.length > 0) { const lastSelectedId = selectedIds[selectedIds.length - 1] const lastSelectedIndex = flatJobs?.findIndex( (jobOrDate) => diff --git a/frontend/src/lib/svelte5Utils.svelte.ts b/frontend/src/lib/svelte5Utils.svelte.ts index 46ec543363..8bd0ffb9b4 100644 --- a/frontend/src/lib/svelte5Utils.svelte.ts +++ b/frontend/src/lib/svelte5Utils.svelte.ts @@ -416,31 +416,33 @@ export function useInfiniteQuery( } } -export function useKeyboardModifiers(): { - shift: boolean - control: boolean - meta: boolean - command: boolean -} { +export function useKeyPressed( + keys: Key[], + params?: { + onKeyUp?: (key: Key, e: KeyboardEvent) => void + onKeyDown?: (key: Key, e: KeyboardEvent) => void + } +): Record { if (typeof window === 'undefined') - return { shift: false, control: false, meta: false, command: false } - let _shift = $state(false) - let control = $state(false) - let meta = $state(false) - let command = $state(false) + return Object.fromEntries(keys.map((key) => [key, false])) as Record + let obj = $state(Object.fromEntries(keys.map((key) => [key, false])) as Record) $effect(() => { const handleKeyDown = (event: KeyboardEvent) => { - if (event.key === 'Shift') _shift = true - else if (event.key === 'Control') control = true - else if (event.key === 'Meta') meta = true - else if (event.key === 'Command') command = true + for (const key of keys) { + if (event.key.toLowerCase() === key.toLowerCase()) { + obj[key] = true + params?.onKeyDown?.(key, event) + } + } } const handleKeyUp = (event: KeyboardEvent) => { - if (event.key === 'Shift') _shift = false - else if (event.key === 'Control') control = false - else if (event.key === 'Meta') meta = false - else if (event.key === 'Command') command = false + for (const key of keys) { + if (event.key.toLowerCase() === key.toLowerCase()) { + obj[key] = false + params?.onKeyUp?.(key, event) + } + } } window.addEventListener('keydown', handleKeyDown) window.addEventListener('keyup', handleKeyUp) @@ -449,18 +451,5 @@ export function useKeyboardModifiers(): { window.removeEventListener('keyup', handleKeyUp) } }) - return { - get shift() { - return _shift - }, - get control() { - return control - }, - get meta() { - return meta - }, - get command() { - return command - } - } + return obj }