mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2025-08-26 14:19:24 +00:00
Fix right rail interaction
This commit is contained in:
parent
e63572197d
commit
2c5354fa1d
@ -320,6 +320,20 @@ const PageEditor = ({
|
|||||||
undoManagerRef.current.executeCommand(pageBreakAllCommand);
|
undoManagerRef.current.executeCommand(pageBreakAllCommand);
|
||||||
}, [displayDocument]);
|
}, [displayDocument]);
|
||||||
|
|
||||||
|
const handleSelectAll = useCallback(() => {
|
||||||
|
if (!displayDocument) return;
|
||||||
|
const allPageNumbers = Array.from({ length: displayDocument.pages.length }, (_, i) => i + 1);
|
||||||
|
setSelectedPageNumbers(allPageNumbers);
|
||||||
|
}, [displayDocument]);
|
||||||
|
|
||||||
|
const handleDeselectAll = useCallback(() => {
|
||||||
|
setSelectedPageNumbers([]);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleSetSelectedPages = useCallback((pageNumbers: number[]) => {
|
||||||
|
setSelectedPageNumbers(pageNumbers);
|
||||||
|
}, []);
|
||||||
|
|
||||||
const handleReorderPages = useCallback((sourcePageNumber: number, targetIndex: number, selectedPages?: number[]) => {
|
const handleReorderPages = useCallback((sourcePageNumber: number, targetIndex: number, selectedPages?: number[]) => {
|
||||||
if (!displayDocument) return;
|
if (!displayDocument) return;
|
||||||
|
|
||||||
@ -548,6 +562,9 @@ const PageEditor = ({
|
|||||||
handleSplitAll,
|
handleSplitAll,
|
||||||
handlePageBreak,
|
handlePageBreak,
|
||||||
handlePageBreakAll,
|
handlePageBreakAll,
|
||||||
|
handleSelectAll,
|
||||||
|
handleDeselectAll,
|
||||||
|
handleSetSelectedPages,
|
||||||
showExportPreview: handleExportPreview,
|
showExportPreview: handleExportPreview,
|
||||||
onExportSelected,
|
onExportSelected,
|
||||||
onExportAll,
|
onExportAll,
|
||||||
@ -562,7 +579,7 @@ const PageEditor = ({
|
|||||||
}
|
}
|
||||||
}, [
|
}, [
|
||||||
onFunctionsReady, handleUndo, handleRedo, canUndo, canRedo, handleRotate, handleDelete, handleSplit, handleSplitAll,
|
onFunctionsReady, handleUndo, handleRedo, canUndo, canRedo, handleRotate, handleDelete, handleSplit, handleSplitAll,
|
||||||
handlePageBreak, handlePageBreakAll, handleExportPreview, onExportSelected, onExportAll, applyChanges, exportLoading,
|
handlePageBreak, handlePageBreakAll, handleSelectAll, handleDeselectAll, handleSetSelectedPages, handleExportPreview, onExportSelected, onExportAll, applyChanges, exportLoading,
|
||||||
selectionMode, selectedPageNumbers, splitPositions, displayDocument?.pages.length, closePdf
|
selectionMode, selectedPageNumbers, splitPositions, displayDocument?.pages.length, closePdf
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@ -226,14 +226,12 @@ const PageThumbnail: React.FC<PageThumbnailProps> = ({
|
|||||||
|
|
||||||
// Handle click vs drag differentiation
|
// Handle click vs drag differentiation
|
||||||
const handleMouseDown = useCallback((e: React.MouseEvent) => {
|
const handleMouseDown = useCallback((e: React.MouseEvent) => {
|
||||||
if (!selectionMode) return;
|
|
||||||
|
|
||||||
setIsMouseDown(true);
|
setIsMouseDown(true);
|
||||||
setMouseStartPos({ x: e.clientX, y: e.clientY });
|
setMouseStartPos({ x: e.clientX, y: e.clientY });
|
||||||
}, [selectionMode]);
|
}, []);
|
||||||
|
|
||||||
const handleMouseUp = useCallback((e: React.MouseEvent) => {
|
const handleMouseUp = useCallback((e: React.MouseEvent) => {
|
||||||
if (!selectionMode || !isMouseDown || !mouseStartPos) {
|
if (!isMouseDown || !mouseStartPos) {
|
||||||
setIsMouseDown(false);
|
setIsMouseDown(false);
|
||||||
setMouseStartPos(null);
|
setMouseStartPos(null);
|
||||||
return;
|
return;
|
||||||
@ -251,7 +249,7 @@ const PageThumbnail: React.FC<PageThumbnailProps> = ({
|
|||||||
|
|
||||||
setIsMouseDown(false);
|
setIsMouseDown(false);
|
||||||
setMouseStartPos(null);
|
setMouseStartPos(null);
|
||||||
}, [selectionMode, isMouseDown, mouseStartPos, isDragging, page.pageNumber, onTogglePage]);
|
}, [isMouseDown, mouseStartPos, isDragging, page.pageNumber, onTogglePage]);
|
||||||
|
|
||||||
const handleMouseLeave = useCallback(() => {
|
const handleMouseLeave = useCallback(() => {
|
||||||
setIsMouseDown(false);
|
setIsMouseDown(false);
|
||||||
|
@ -45,19 +45,14 @@ export default function RightRail() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (currentView === 'pageEditor') {
|
if (currentView === 'pageEditor') {
|
||||||
let totalItems = 0;
|
// Use PageEditor's own state
|
||||||
fileRecords.forEach(rec => {
|
const totalItems = pageEditorFunctions?.totalPages || 0;
|
||||||
const pf = rec.processedFile;
|
const selectedCount = pageEditorFunctions?.selectedPages?.length || 0;
|
||||||
if (pf) {
|
|
||||||
totalItems += (pf.totalPages as number) || (pf.pages?.length || 0);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
const selectedCount = Array.isArray(selectedPageNumbers) ? selectedPageNumbers.length : 0;
|
|
||||||
return { totalItems, selectedCount };
|
return { totalItems, selectedCount };
|
||||||
}
|
}
|
||||||
|
|
||||||
return { totalItems: 0, selectedCount: 0 };
|
return { totalItems: 0, selectedCount: 0 };
|
||||||
}, [currentView, activeFiles, fileRecords, selectedFileIds, selectedPageNumbers]);
|
}, [currentView, activeFiles, selectedFileIds, pageEditorFunctions]);
|
||||||
|
|
||||||
const { totalItems, selectedCount } = getSelectionState();
|
const { totalItems, selectedCount } = getSelectionState();
|
||||||
|
|
||||||
@ -70,19 +65,10 @@ export default function RightRail() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (currentView === 'pageEditor') {
|
if (currentView === 'pageEditor') {
|
||||||
let totalPages = 0;
|
// Use PageEditor's select all function
|
||||||
fileRecords.forEach(rec => {
|
pageEditorFunctions?.handleSelectAll?.();
|
||||||
const pf = rec.processedFile;
|
|
||||||
if (pf) {
|
|
||||||
totalPages += (pf.totalPages as number) || (pf.pages?.length || 0);
|
|
||||||
}
|
}
|
||||||
});
|
}, [currentView, state.files.ids, setSelectedFiles, pageEditorFunctions]);
|
||||||
|
|
||||||
if (totalPages > 0) {
|
|
||||||
setSelectedPages(Array.from({ length: totalPages }, (_, i) => i + 1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, [currentView, state.files.ids, fileRecords, setSelectedFiles, setSelectedPages]);
|
|
||||||
|
|
||||||
const handleDeselectAll = useCallback(() => {
|
const handleDeselectAll = useCallback(() => {
|
||||||
if (currentView === 'fileEditor' || currentView === 'viewer') {
|
if (currentView === 'fileEditor' || currentView === 'viewer') {
|
||||||
@ -90,9 +76,10 @@ export default function RightRail() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (currentView === 'pageEditor') {
|
if (currentView === 'pageEditor') {
|
||||||
setSelectedPages([]);
|
// Use PageEditor's deselect all function
|
||||||
|
pageEditorFunctions?.handleDeselectAll?.();
|
||||||
}
|
}
|
||||||
}, [currentView, setSelectedFiles, setSelectedPages]);
|
}, [currentView, setSelectedFiles, pageEditorFunctions]);
|
||||||
|
|
||||||
const handleExportAll = useCallback(() => {
|
const handleExportAll = useCallback(() => {
|
||||||
if (currentView === 'fileEditor' || currentView === 'viewer') {
|
if (currentView === 'fileEditor' || currentView === 'viewer') {
|
||||||
@ -151,24 +138,21 @@ export default function RightRail() {
|
|||||||
|
|
||||||
const updatePagesFromCSV = useCallback(() => {
|
const updatePagesFromCSV = useCallback(() => {
|
||||||
const rawPages = parseCSVInput(csvInput);
|
const rawPages = parseCSVInput(csvInput);
|
||||||
// Determine max page count from processed records
|
// Use PageEditor's total pages for validation
|
||||||
const maxPages = fileRecords.reduce((sum, rec) => {
|
const maxPages = pageEditorFunctions?.totalPages || 0;
|
||||||
const pf = rec.processedFile;
|
|
||||||
if (!pf) return sum;
|
|
||||||
return sum + ((pf.totalPages as number) || (pf.pages?.length || 0));
|
|
||||||
}, 0);
|
|
||||||
const normalized = Array.from(new Set(rawPages.filter(n => Number.isFinite(n) && n > 0 && n <= maxPages))).sort((a,b)=>a-b);
|
const normalized = Array.from(new Set(rawPages.filter(n => Number.isFinite(n) && n > 0 && n <= maxPages))).sort((a,b)=>a-b);
|
||||||
setSelectedPages(normalized);
|
// Use PageEditor's function to set selected pages
|
||||||
}, [csvInput, parseCSVInput, fileRecords, setSelectedPages]);
|
pageEditorFunctions?.handleSetSelectedPages?.(normalized);
|
||||||
|
}, [csvInput, parseCSVInput, pageEditorFunctions]);
|
||||||
|
|
||||||
// Sync csvInput with selectedPageNumbers changes
|
// Sync csvInput with PageEditor's selected pages
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const sortedPageNumbers = Array.isArray(selectedPageNumbers)
|
const sortedPageNumbers = Array.isArray(pageEditorFunctions?.selectedPages)
|
||||||
? [...selectedPageNumbers].sort((a, b) => a - b)
|
? [...pageEditorFunctions.selectedPages].sort((a, b) => a - b)
|
||||||
: [];
|
: [];
|
||||||
const newCsvInput = sortedPageNumbers.join(', ');
|
const newCsvInput = sortedPageNumbers.join(', ');
|
||||||
setCsvInput(newCsvInput);
|
setCsvInput(newCsvInput);
|
||||||
}, [selectedPageNumbers]);
|
}, [pageEditorFunctions?.selectedPages]);
|
||||||
|
|
||||||
// Clear CSV input when files change (use stable signature to avoid ref churn)
|
// Clear CSV input when files change (use stable signature to avoid ref churn)
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -278,7 +262,7 @@ export default function RightRail() {
|
|||||||
<BulkSelectionPanel
|
<BulkSelectionPanel
|
||||||
csvInput={csvInput}
|
csvInput={csvInput}
|
||||||
setCsvInput={setCsvInput}
|
setCsvInput={setCsvInput}
|
||||||
selectedPages={Array.isArray(selectedPageNumbers) ? selectedPageNumbers : []}
|
selectedPages={Array.isArray(pageEditorFunctions?.selectedPages) ? pageEditorFunctions.selectedPages : []}
|
||||||
onUpdatePagesFromCSV={updatePagesFromCSV}
|
onUpdatePagesFromCSV={updatePagesFromCSV}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -299,8 +283,8 @@ export default function RightRail() {
|
|||||||
variant="subtle"
|
variant="subtle"
|
||||||
radius="md"
|
radius="md"
|
||||||
className="right-rail-icon"
|
className="right-rail-icon"
|
||||||
onClick={() => { pageEditorFunctions?.handleDelete?.(); setSelectedPages([]); }}
|
onClick={() => { pageEditorFunctions?.handleDelete?.(); }}
|
||||||
disabled={!pageControlsVisible || (Array.isArray(selectedPageNumbers) ? selectedPageNumbers.length === 0 : true)}
|
disabled={!pageControlsVisible || (pageEditorFunctions?.selectedPages?.length || 0) === 0}
|
||||||
aria-label={typeof t === 'function' ? t('rightRail.deleteSelected', 'Delete Selected Pages') : 'Delete Selected Pages'}
|
aria-label={typeof t === 'function' ? t('rightRail.deleteSelected', 'Delete Selected Pages') : 'Delete Selected Pages'}
|
||||||
>
|
>
|
||||||
<LocalIcon icon="delete-outline-rounded" width="1.5rem" height="1.5rem" />
|
<LocalIcon icon="delete-outline-rounded" width="1.5rem" height="1.5rem" />
|
||||||
|
@ -53,6 +53,9 @@ export interface PageEditorFunctions {
|
|||||||
handleSplitAll: () => void;
|
handleSplitAll: () => void;
|
||||||
handlePageBreak: () => void;
|
handlePageBreak: () => void;
|
||||||
handlePageBreakAll: () => void;
|
handlePageBreakAll: () => void;
|
||||||
|
handleSelectAll: () => void;
|
||||||
|
handleDeselectAll: () => void;
|
||||||
|
handleSetSelectedPages: (pageNumbers: number[]) => void;
|
||||||
onExportSelected: () => void;
|
onExportSelected: () => void;
|
||||||
onExportAll: () => void;
|
onExportAll: () => void;
|
||||||
exportLoading: boolean;
|
exportLoading: boolean;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user