feat: enable diff and preview panels on smaller screens (#1524)
On screens < 1280px, users can now access Preview and Diffs views via toggle buttons in the header, creating a tab-like experience. Changes: - Remove isXL check from AttemptHeaderActions toggle buttons - Simplify mobile layout to switch between attempt/aux content based on mode - Keyboard shortcuts (Cmd/Ctrl+Enter) now cycle through views on mobile Closes #1523
This commit is contained in:
committed by
GitHub
parent
4e158df3d0
commit
20352f2893
@@ -279,53 +279,27 @@ export function TasksLayout({
|
|||||||
const desktopKey = isPanelOpen ? 'desktop-with-panel' : 'kanban-only';
|
const desktopKey = isPanelOpen ? 'desktop-with-panel' : 'kanban-only';
|
||||||
|
|
||||||
if (isMobile) {
|
if (isMobile) {
|
||||||
const columns = isPanelOpen ? ['0fr', '1fr', '0fr'] : ['1fr', '0fr', '0fr'];
|
// When panel is open and mode is set, show aux content (preview/diffs)
|
||||||
const gridTemplateColumns = `minmax(0, ${columns[0]}) minmax(0, ${columns[1]}) minmax(0, ${columns[2]})`;
|
// Otherwise show attempt content
|
||||||
const isKanbanVisible = columns[0] !== '0fr';
|
const showAux = isPanelOpen && mode !== null;
|
||||||
const isAttemptVisible = columns[1] !== '0fr';
|
|
||||||
const isAuxVisible = columns[2] !== '0fr';
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div className="h-full min-h-0 flex flex-col">
|
||||||
className="h-full min-h-0 grid"
|
{/* Header is visible when panel is open */}
|
||||||
style={{
|
{isPanelOpen && rightHeader && (
|
||||||
gridTemplateColumns,
|
<div className="shrink-0 sticky top-0 z-20 bg-background border-b">
|
||||||
transition: 'grid-template-columns 250ms cubic-bezier(0.2, 0, 0, 1)',
|
{rightHeader}
|
||||||
}}
|
</div>
|
||||||
>
|
)}
|
||||||
<div
|
|
||||||
className="min-w-0 min-h-0 overflow-hidden"
|
|
||||||
aria-hidden={!isKanbanVisible}
|
|
||||||
aria-label="Kanban board"
|
|
||||||
role="region"
|
|
||||||
style={{ pointerEvents: isKanbanVisible ? 'auto' : 'none' }}
|
|
||||||
>
|
|
||||||
{kanban}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
<div className="flex-1 min-h-0">
|
||||||
className="min-w-0 min-h-0 overflow-hidden border-l flex flex-col"
|
{!isPanelOpen ? (
|
||||||
aria-hidden={!isAttemptVisible}
|
kanban
|
||||||
aria-label="Details"
|
) : showAux ? (
|
||||||
role="region"
|
<AuxRouter mode={mode} aux={aux} />
|
||||||
style={{ pointerEvents: isAttemptVisible ? 'auto' : 'none' }}
|
) : (
|
||||||
>
|
attempt
|
||||||
{rightHeader && (
|
|
||||||
<div className="shrink-0 sticky top-0 z-20 bg-background border-b">
|
|
||||||
{rightHeader}
|
|
||||||
</div>
|
|
||||||
)}
|
)}
|
||||||
<div className="flex-1 min-h-0">{attempt}</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
className="min-w-0 min-h-0 overflow-hidden border-l"
|
|
||||||
aria-hidden={!isAuxVisible}
|
|
||||||
aria-label={mode === 'preview' ? 'Preview' : 'Diffs'}
|
|
||||||
role="region"
|
|
||||||
style={{ pointerEvents: isAuxVisible ? 'auto' : 'none' }}
|
|
||||||
>
|
|
||||||
{aux}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import type { LayoutMode } from '../layout/TasksLayout';
|
|||||||
import type { TaskAttempt, TaskWithAttemptStatus } from 'shared/types';
|
import type { TaskAttempt, TaskWithAttemptStatus } from 'shared/types';
|
||||||
import { ActionsDropdown } from '../ui/actions-dropdown';
|
import { ActionsDropdown } from '../ui/actions-dropdown';
|
||||||
import { usePostHog } from 'posthog-js/react';
|
import { usePostHog } from 'posthog-js/react';
|
||||||
import { useMediaQuery } from '@/hooks/useMediaQuery';
|
|
||||||
import type { SharedTaskRecord } from '@/hooks/useProjectTasks';
|
import type { SharedTaskRecord } from '@/hooks/useProjectTasks';
|
||||||
|
|
||||||
interface AttemptHeaderActionsProps {
|
interface AttemptHeaderActionsProps {
|
||||||
@@ -34,11 +33,10 @@ export const AttemptHeaderActions = ({
|
|||||||
}: AttemptHeaderActionsProps) => {
|
}: AttemptHeaderActionsProps) => {
|
||||||
const { t } = useTranslation('tasks');
|
const { t } = useTranslation('tasks');
|
||||||
const posthog = usePostHog();
|
const posthog = usePostHog();
|
||||||
const isXL = useMediaQuery('(min-width: 1280px)');
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{typeof mode !== 'undefined' && onModeChange && isXL && (
|
{typeof mode !== 'undefined' && onModeChange && (
|
||||||
<TooltipProvider>
|
<TooltipProvider>
|
||||||
<ToggleGroup
|
<ToggleGroup
|
||||||
type="single"
|
type="single"
|
||||||
@@ -106,7 +104,7 @@ export const AttemptHeaderActions = ({
|
|||||||
</ToggleGroup>
|
</ToggleGroup>
|
||||||
</TooltipProvider>
|
</TooltipProvider>
|
||||||
)}
|
)}
|
||||||
{typeof mode !== 'undefined' && onModeChange && isXL && (
|
{typeof mode !== 'undefined' && onModeChange && (
|
||||||
<div className="h-4 w-px bg-border" />
|
<div className="h-4 w-px bg-border" />
|
||||||
)}
|
)}
|
||||||
<ActionsDropdown task={task} attempt={attempt} sharedTask={sharedTask} />
|
<ActionsDropdown task={task} attempt={attempt} sharedTask={sharedTask} />
|
||||||
|
|||||||
Reference in New Issue
Block a user