mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 01:15:03 +03:00
<img width="1454" height="786" alt="image" src="https://github.com/user-attachments/assets/995790b1-a242-4a61-a0a0-349de7234923" /> Stack 4/4 · previous: #50688 ## Problem Selecting several logs to copy or send to the Assistant meant using a separate checkbox column and a banner above the table. Clicking a row and checking a row were two different selections. ## Solution - Unified Logs uses `useTableRowSelection`, so a row click, Cmd/Ctrl-click, Shift-click, and the checkbox all act on one selection. The selection resets when the project or filters change, and a linked `?id=` still restores its log. - The level indicator and checkbox now share one column. The checkbox shows on hover, focus, or when the row is selected. - The detail panel shows every selected log: one log gets the tabs, and two or more show their combined JSON. Copy-as-JSON and "Explain with AI" move into the panel header (`LogSelectionActions`), replacing `RowSelectionHeader`. - New Shift+↑ / Shift+↓ shortcuts extend the selection, with a hint in the panel footer. Prev/next navigation follows display order and keeps the row in view. - `LogTypeIcon` no longer puts a nested button inside clickable rows. ## Review instructions 1. Click a log, then Shift-click another. The range should be selected and the panel should show the combined JSON. 2. Cmd-click to add or remove single logs. Use the copy button (or its shortcut) and "Explain with AI". 3. With the panel open, press Shift+↑ / Shift+↓ to grow and shrink the selection. 4. Change a filter. The selection should clear. ## Checklist - [ ] I have read [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Summary * **New Features** * Added multi-row selection in Unified Logs, including additive, range, checkbox, and keyboard selection. * Added bulk JSON viewing and copying, plus AI-assisted actions for selected logs. * Added Shift+Arrow shortcuts to extend selections and improved row navigation. * **Accessibility** * Improved labels and focus behavior for log controls and log type indicators. * **Bug Fixes** * Kept single-log Overview and Raw JSON views available alongside multi-log selection. * Applied metadata visibility settings to selected-log actions and disabled actions for invalid log data. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
77 lines
2.8 KiB
TypeScript
77 lines
2.8 KiB
TypeScript
import { useRef } from 'react'
|
|
import { AiIconAnimation } from 'ui'
|
|
|
|
import { buildLogsPrompt, formatLogsAsJson } from '../Settings/Logs/Logs.utils'
|
|
import { parseSelectedLogs } from './LogSelectionActions.utils'
|
|
import { SIDEBAR_KEYS } from '@/components/layouts/ProjectLayout/LayoutSidebar/LayoutSidebarProvider'
|
|
import { ButtonTooltip } from '@/components/ui/ButtonTooltip'
|
|
import CopyButton from '@/components/ui/CopyButton'
|
|
import { Shortcut } from '@/components/ui/Shortcut'
|
|
import { useIsFeatureEnabled } from '@/hooks/misc/useIsFeatureEnabled'
|
|
import { useTrack } from '@/lib/telemetry/track'
|
|
import { useAiAssistantStateSnapshot } from '@/state/ai-assistant-state'
|
|
import { SHORTCUT_IDS } from '@/state/shortcuts/registry'
|
|
import { useSidebarManagerSnapshot } from '@/state/sidebar-manager-state'
|
|
|
|
export const LogSelectionActions = ({ rows }: { rows: unknown[] }) => {
|
|
const { openSidebar } = useSidebarManagerSnapshot()
|
|
const aiSnap = useAiAssistantStateSnapshot()
|
|
const track = useTrack()
|
|
const copyButtonRef = useRef<HTMLButtonElement>(null)
|
|
|
|
const { logsMetadata } = useIsFeatureEnabled(['logs:metadata'])
|
|
const selectedLogs = parseSelectedLogs(rows, logsMetadata)
|
|
const selectedRows = selectedLogs.success ? selectedLogs.data : []
|
|
const hasValidSelection = selectedRows.length > 0
|
|
|
|
const handleOpenAiAssistant = () => {
|
|
if (!hasValidSelection) return
|
|
const prompt = buildLogsPrompt(selectedRows)
|
|
openSidebar(SIDEBAR_KEYS.AI_ASSISTANT)
|
|
aiSnap.newChat({ initialMessage: prompt })
|
|
track('ai_assistant_dropdown_button_clicked', { source: 'log_explorer' })
|
|
}
|
|
|
|
// Click the button so the shortcut shows the same copied feedback
|
|
const handleCopyShortcut = () => copyButtonRef.current?.click()
|
|
|
|
return (
|
|
<div className="flex items-center gap-1">
|
|
{!selectedLogs.success && (
|
|
<span role="alert" className="text-xs text-destructive">
|
|
Selected logs contain invalid data.
|
|
</span>
|
|
)}
|
|
<Shortcut
|
|
id={SHORTCUT_IDS.RESULTS_COPY_JSON}
|
|
onTrigger={handleCopyShortcut}
|
|
options={{ enabled: hasValidSelection, registerInCommandMenu: true }}
|
|
side="bottom"
|
|
label="Copy selected logs as JSON"
|
|
>
|
|
<CopyButton
|
|
ref={copyButtonRef}
|
|
iconOnly
|
|
size="tiny"
|
|
variant="text"
|
|
className="px-1"
|
|
aria-label="Copy selected logs"
|
|
disabled={!hasValidSelection}
|
|
asyncText={() => formatLogsAsJson(selectedRows)}
|
|
/>
|
|
</Shortcut>
|
|
|
|
<ButtonTooltip
|
|
size="tiny"
|
|
variant="text"
|
|
className="px-1"
|
|
icon={<AiIconAnimation size={16} />}
|
|
aria-label="Explain with AI"
|
|
disabled={!hasValidSelection}
|
|
tooltip={{ content: { side: 'bottom', text: 'Explain with AI' } }}
|
|
onClick={handleOpenAiAssistant}
|
|
/>
|
|
</div>
|
|
)
|
|
}
|