diff --git a/frontend/src/components/pageEditor/BulkSelectionPanel.module.css b/frontend/src/components/pageEditor/BulkSelectionPanel.module.css index ca40cdc96..ca4e02b08 100644 --- a/frontend/src/components/pageEditor/BulkSelectionPanel.module.css +++ b/frontend/src/components/pageEditor/BulkSelectionPanel.module.css @@ -146,9 +146,9 @@ .selectedList { max-height: 8rem; overflow: auto; - border: 0.0625rem solid var(--mantine-color-gray-3); - border-radius: 0.25rem; - padding: 0.5rem; + background-color: var(--mantine-color-gray-0); + border-radius: 0.5rem; + padding: 0.5rem 0.75rem; margin-top: 0.5rem; min-width: 24rem; } @@ -232,3 +232,30 @@ flex-shrink: 0; } +/* Error helper text above the input */ +.errorText { + margin-top: 0.25rem; + color: var(--mantine-color-red-6); +} + +/* Dark-mode adjustments */ +::global([data-mantine-color-scheme='dark']) .selectedList { + background-color: var(--mantine-color-dark-6); +} + +/* Small screens: allow the section to shrink instead of enforcing a large min width */ +@media (max-width: 480px) { + .panelGroup, + .selectedList, + .advancedSection, + .panelContainer { + min-width: 0; + } +} + +/* Outermost panel container scrolling */ +.panelContainer { + max-height: 95vh; + overflow: auto; +} + diff --git a/frontend/src/components/pageEditor/BulkSelectionPanel.tsx b/frontend/src/components/pageEditor/BulkSelectionPanel.tsx index dc3b12937..6449062a6 100644 --- a/frontend/src/components/pageEditor/BulkSelectionPanel.tsx +++ b/frontend/src/components/pageEditor/BulkSelectionPanel.tsx @@ -1,9 +1,10 @@ -import { useState } from 'react'; +import { useState, useEffect } from 'react'; import { Group, TextInput, Button, Text, NumberInput, Flex } from '@mantine/core'; import LocalIcon from '../shared/LocalIcon'; import { Tooltip } from '../shared/Tooltip'; import { usePageSelectionTips } from '../tooltips/usePageSelectionTips'; import classes from './BulkSelectionPanel.module.css'; +import { parseSelectionWithDiagnostics } from '../../utils/bulkselection/parseSelection'; import { appendExpression, insertOperatorSmart, @@ -38,10 +39,26 @@ const BulkSelectionPanel = ({ const [firstNError, setFirstNError] = useState(null); const [lastNError, setLastNError] = useState(null); const [rangeError, setRangeError] = useState(null); + const [syntaxError, setSyntaxError] = useState(null); const maxPages = displayDocument?.pages?.length ?? 0; + // Validate input syntax and show lightweight feedback + useEffect(() => { + const text = (csvInput || '').trim(); + if (!text) { + setSyntaxError(null); + return; + } + try { + const { warning } = parseSelectionWithDiagnostics(text, maxPages); + setSyntaxError(warning ? 'There is a syntax issue. See Page Selection tips for help.' : null); + } catch { + setSyntaxError('There is a syntax issue. See Page Selection tips for help.'); + } + }, [csvInput, maxPages]); + const applyExpression = (expr: string) => { const nextInput = appendExpression(csvInput, expr); setCsvInput(nextInput); @@ -62,7 +79,10 @@ const BulkSelectionPanel = ({ }; return ( - <> +
+ {syntaxError && ( + {syntaxError} + )} } - onBlur={() => onUpdatePagesFromCSV()} onKeyDown={(e) => e.key === 'Enter' && onUpdatePagesFromCSV()} className={classes.textInput} /> @@ -364,7 +383,7 @@ const BulkSelectionPanel = ({
)} - + ); };