Выдение ячеек по клику
This commit is contained in:
@@ -19,6 +19,8 @@ import {
|
|||||||
} from './types'
|
} from './types'
|
||||||
import {
|
import {
|
||||||
convertReferencesToHighlights,
|
convertReferencesToHighlights,
|
||||||
|
createCellAddress,
|
||||||
|
createQualifiedCellReference,
|
||||||
extractCellReferences,
|
extractCellReferences,
|
||||||
getColumnLabel,
|
getColumnLabel,
|
||||||
} from './utils'
|
} from './utils'
|
||||||
@@ -67,6 +69,8 @@ const DualSpreadsheet: FC<DualSpreadsheetProps> = ({
|
|||||||
} | null>(null)
|
} | null>(null)
|
||||||
const [isEditing, setIsEditing] = useState(false)
|
const [isEditing, setIsEditing] = useState(false)
|
||||||
const [editingValue, setEditingValue] = useState<string>('') // Локальное значение во время редактирования
|
const [editingValue, setEditingValue] = useState<string>('') // Локальное значение во время редактирования
|
||||||
|
// Источник ввода: 'cell' (редактирование внутри ячейки) или 'formula'
|
||||||
|
const [editingSource, setEditingSource] = useState<'cell' | 'formula'>('cell')
|
||||||
const [isInitialized, setIsInitialized] = useState(false)
|
const [isInitialized, setIsInitialized] = useState(false)
|
||||||
const [baseFileData, setBaseFileData] = useState<
|
const [baseFileData, setBaseFileData] = useState<
|
||||||
Record<string, Record<string, any>>
|
Record<string, Record<string, any>>
|
||||||
@@ -427,6 +431,7 @@ const DualSpreadsheet: FC<DualSpreadsheetProps> = ({
|
|||||||
}
|
}
|
||||||
setIsEditing(false)
|
setIsEditing(false)
|
||||||
setEditingValue('')
|
setEditingValue('')
|
||||||
|
setEditingSource('cell')
|
||||||
containerRefs.current[activeSheet]?.focus({ preventScroll: true })
|
containerRefs.current[activeSheet]?.focus({ preventScroll: true })
|
||||||
},
|
},
|
||||||
[activeSheet, selectedCell, editingValue, multiSheetEngine, updateRevision]
|
[activeSheet, selectedCell, editingValue, multiSheetEngine, updateRevision]
|
||||||
@@ -497,8 +502,14 @@ const DualSpreadsheet: FC<DualSpreadsheetProps> = ({
|
|||||||
ArrowDown: () => moveSelection(1, 0),
|
ArrowDown: () => moveSelection(1, 0),
|
||||||
ArrowLeft: () => moveSelection(0, -1),
|
ArrowLeft: () => moveSelection(0, -1),
|
||||||
ArrowRight: () => moveSelection(0, 1),
|
ArrowRight: () => moveSelection(0, 1),
|
||||||
Enter: () => startEditing(),
|
Enter: () => {
|
||||||
F2: () => startEditing(),
|
setEditingSource('cell')
|
||||||
|
startEditing()
|
||||||
|
},
|
||||||
|
F2: () => {
|
||||||
|
setEditingSource('cell')
|
||||||
|
startEditing()
|
||||||
|
},
|
||||||
Delete: handleClearCell,
|
Delete: handleClearCell,
|
||||||
Backspace: handleClearCell,
|
Backspace: handleClearCell,
|
||||||
}
|
}
|
||||||
@@ -508,6 +519,7 @@ const DualSpreadsheet: FC<DualSpreadsheetProps> = ({
|
|||||||
keyHandlers[e.key]()
|
keyHandlers[e.key]()
|
||||||
} else if (e.key.length === 1 && !e.ctrlKey && !e.metaKey) {
|
} else if (e.key.length === 1 && !e.ctrlKey && !e.metaKey) {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
setEditingSource('cell')
|
||||||
setEditingValue(e.key)
|
setEditingValue(e.key)
|
||||||
setIsEditing(true)
|
setIsEditing(true)
|
||||||
}
|
}
|
||||||
@@ -517,6 +529,13 @@ const DualSpreadsheet: FC<DualSpreadsheetProps> = ({
|
|||||||
|
|
||||||
const handleCellClick = useCallback(
|
const handleCellClick = useCallback(
|
||||||
(row: number, col: number) => {
|
(row: number, col: number) => {
|
||||||
|
console.log('🖱️ Обычный клик по ячейке:', {
|
||||||
|
row,
|
||||||
|
col,
|
||||||
|
isEditing,
|
||||||
|
activeSheet,
|
||||||
|
})
|
||||||
|
|
||||||
if (isEditing) {
|
if (isEditing) {
|
||||||
stopEditing(true)
|
stopEditing(true)
|
||||||
}
|
}
|
||||||
@@ -526,9 +545,71 @@ const DualSpreadsheet: FC<DualSpreadsheetProps> = ({
|
|||||||
[isEditing, stopEditing, activeSheet]
|
[isEditing, stopEditing, activeSheet]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Новый обработчик для кликов в режиме редактирования - вставляет ссылку
|
||||||
|
const handleCellReferenceClick = useCallback(
|
||||||
|
(targetSheetType: SheetType, row: number, col: number) => {
|
||||||
|
console.log('🔗 Клик для вставки ссылки:', {
|
||||||
|
targetSheetType,
|
||||||
|
row,
|
||||||
|
col,
|
||||||
|
isEditing,
|
||||||
|
selectedCell,
|
||||||
|
editingValue,
|
||||||
|
})
|
||||||
|
|
||||||
|
// Проверяем, что мы в режиме редактирования
|
||||||
|
if (!isEditing || !selectedCell) {
|
||||||
|
console.log(
|
||||||
|
'⚠️ Игнорируем клик ссылки: не в режиме редактирования или нет выбранной ячейки'
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Создаем ссылку на ячейку
|
||||||
|
let cellReference: string
|
||||||
|
|
||||||
|
// Если это другой лист, делаем квалифицированную ссылку
|
||||||
|
if (targetSheetType !== activeSheet) {
|
||||||
|
cellReference = createQualifiedCellReference(targetSheetType, row, col)
|
||||||
|
console.log('📋 Создана межлистовая ссылка:', cellReference)
|
||||||
|
} else {
|
||||||
|
// Если это тот же лист, делаем локальную ссылку
|
||||||
|
cellReference = createCellAddress(row, col)
|
||||||
|
console.log('📋 Создана локальная ссылка:', cellReference)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Добавляем ссылку к текущему значению редактирования
|
||||||
|
const newValue = editingValue + cellReference
|
||||||
|
console.log('✏️ Новое значение формулы:', {
|
||||||
|
oldValue: editingValue,
|
||||||
|
newValue,
|
||||||
|
})
|
||||||
|
|
||||||
|
setEditingValue(newValue)
|
||||||
|
|
||||||
|
if (editingSource === 'formula') {
|
||||||
|
if (formulaBarRef.current) {
|
||||||
|
formulaBarRef.current.value = newValue
|
||||||
|
formulaBarRef.current.focus()
|
||||||
|
const length = newValue.length
|
||||||
|
formulaBarRef.current.setSelectionRange(length, length)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (activeCellInputRef.current) {
|
||||||
|
activeCellInputRef.current.value = newValue
|
||||||
|
activeCellInputRef.current.focus({ preventScroll: true })
|
||||||
|
const length = newValue.length
|
||||||
|
activeCellInputRef.current.setSelectionRange(length, length)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[isEditing, selectedCell, editingValue, activeSheet, editingSource]
|
||||||
|
)
|
||||||
|
|
||||||
const handleCellDoubleClick = useCallback(
|
const handleCellDoubleClick = useCallback(
|
||||||
(row: number, col: number) => {
|
(row: number, col: number) => {
|
||||||
setSelectedCell({ row, col })
|
setSelectedCell({ row, col })
|
||||||
|
setEditingSource('cell')
|
||||||
startEditing()
|
startEditing()
|
||||||
},
|
},
|
||||||
[startEditing]
|
[startEditing]
|
||||||
@@ -563,6 +644,7 @@ const DualSpreadsheet: FC<DualSpreadsheetProps> = ({
|
|||||||
|
|
||||||
const handleFormulaBarFocus = useCallback(() => {
|
const handleFormulaBarFocus = useCallback(() => {
|
||||||
if (selectedCell && !isEditing) {
|
if (selectedCell && !isEditing) {
|
||||||
|
setEditingSource('formula')
|
||||||
startEditing()
|
startEditing()
|
||||||
}
|
}
|
||||||
}, [selectedCell, isEditing, startEditing])
|
}, [selectedCell, isEditing, startEditing])
|
||||||
@@ -864,6 +946,8 @@ const DualSpreadsheet: FC<DualSpreadsheetProps> = ({
|
|||||||
handleCellClick={handleCellClick}
|
handleCellClick={handleCellClick}
|
||||||
handleCellDoubleClick={handleCellDoubleClick}
|
handleCellDoubleClick={handleCellDoubleClick}
|
||||||
handleCellChange={handleCellChange}
|
handleCellChange={handleCellChange}
|
||||||
|
handleCellReferenceClick={handleCellReferenceClick}
|
||||||
|
isInEditMode={isEditing}
|
||||||
stopEditing={stopEditing}
|
stopEditing={stopEditing}
|
||||||
setActiveSheet={setActiveSheet}
|
setActiveSheet={setActiveSheet}
|
||||||
activeCellInputRef={activeCellInputRef}
|
activeCellInputRef={activeCellInputRef}
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ export const Cell = memo(
|
|||||||
onCellClick,
|
onCellClick,
|
||||||
onCellDoubleClick,
|
onCellDoubleClick,
|
||||||
onCellValueChange,
|
onCellValueChange,
|
||||||
|
onCellReferenceClick,
|
||||||
|
isInEditMode,
|
||||||
stopEditing,
|
stopEditing,
|
||||||
setActiveSheet,
|
setActiveSheet,
|
||||||
activeCellRef,
|
activeCellRef,
|
||||||
@@ -105,20 +107,89 @@ export const Cell = memo(
|
|||||||
// Используем обычное значение displayValue для всех ячеек, включая объединенные
|
// Используем обычное значение displayValue для всех ячеек, включая объединенные
|
||||||
const cellDisplayValue = displayValue
|
const cellDisplayValue = displayValue
|
||||||
|
|
||||||
const handleClick = useCallback(() => {
|
const handleClick = useCallback(
|
||||||
setActiveSheet(sheetType)
|
(e: React.MouseEvent) => {
|
||||||
onCellClick(rowIndex, colIndex)
|
console.log('🖱️ Cell клик:', {
|
||||||
}, [setActiveSheet, sheetType, onCellClick, rowIndex, colIndex])
|
rowIndex,
|
||||||
|
colIndex,
|
||||||
|
sheetType,
|
||||||
|
isInEditMode,
|
||||||
|
isSelected,
|
||||||
|
hasReferenceHandler: !!onCellReferenceClick,
|
||||||
|
})
|
||||||
|
|
||||||
|
// Если мы в режиме редактирования, вставка была обработана на mousedown.
|
||||||
|
// Останавливаем всплытие, чтобы родительский Spreadsheet не сменил активный лист.
|
||||||
|
if (isInEditMode) {
|
||||||
|
e.preventDefault()
|
||||||
|
e.stopPropagation()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Обычная логика клика (выделение ячейки)
|
||||||
|
console.log('📍 Обычный клик - выбираем ячейку:', {
|
||||||
|
rowIndex,
|
||||||
|
colIndex,
|
||||||
|
sheetType,
|
||||||
|
})
|
||||||
|
|
||||||
|
// Подсказка для пользователя
|
||||||
|
if (!isInEditMode) {
|
||||||
|
console.log(
|
||||||
|
'💡 Чтобы вставить ссылку на ячейку: 1) Выберите ячейку 2) Нажмите F2 или Enter для редактирования 3) Кликните на нужную ячейку'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
setActiveSheet(sheetType)
|
||||||
|
onCellClick(rowIndex, colIndex)
|
||||||
|
},
|
||||||
|
[
|
||||||
|
setActiveSheet,
|
||||||
|
sheetType,
|
||||||
|
onCellClick,
|
||||||
|
onCellReferenceClick,
|
||||||
|
rowIndex,
|
||||||
|
colIndex,
|
||||||
|
isInEditMode,
|
||||||
|
isSelected,
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
const handleDoubleClick = useCallback(
|
const handleDoubleClick = useCallback(
|
||||||
() => onCellDoubleClick(rowIndex, colIndex),
|
() => onCellDoubleClick(rowIndex, colIndex),
|
||||||
[onCellDoubleClick, rowIndex, colIndex]
|
[onCellDoubleClick, rowIndex, colIndex]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const handleMouseDown = useCallback(
|
||||||
|
(e: React.MouseEvent) => {
|
||||||
|
// Используем mousedown, чтобы сработать раньше blur FormulaBar
|
||||||
|
if (isInEditMode && onCellReferenceClick && !isSelected) {
|
||||||
|
e.preventDefault()
|
||||||
|
e.stopPropagation()
|
||||||
|
console.log('🖱️ mousedown – вставка ссылки до blur:', {
|
||||||
|
rowIndex,
|
||||||
|
colIndex,
|
||||||
|
sheetType,
|
||||||
|
})
|
||||||
|
onCellReferenceClick(sheetType, rowIndex, colIndex)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[
|
||||||
|
isInEditMode,
|
||||||
|
onCellReferenceClick,
|
||||||
|
isSelected,
|
||||||
|
sheetType,
|
||||||
|
rowIndex,
|
||||||
|
colIndex,
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={className}
|
className={className}
|
||||||
style={cellStyle}
|
style={cellStyle}
|
||||||
|
onMouseDown={handleMouseDown}
|
||||||
onClick={handleClick}
|
onClick={handleClick}
|
||||||
onDoubleClick={handleDoubleClick}
|
onDoubleClick={handleDoubleClick}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ export const CellRenderer = ({
|
|||||||
handleCellClick,
|
handleCellClick,
|
||||||
handleCellDoubleClick,
|
handleCellDoubleClick,
|
||||||
handleCellChange,
|
handleCellChange,
|
||||||
|
handleCellReferenceClick,
|
||||||
|
isInEditMode,
|
||||||
stopEditing,
|
stopEditing,
|
||||||
setActiveSheet,
|
setActiveSheet,
|
||||||
activeCellInputRef,
|
activeCellInputRef,
|
||||||
@@ -99,6 +101,8 @@ export const CellRenderer = ({
|
|||||||
onCellClick={handleCellClick}
|
onCellClick={handleCellClick}
|
||||||
onCellDoubleClick={handleCellDoubleClick}
|
onCellDoubleClick={handleCellDoubleClick}
|
||||||
onCellValueChange={handleCellChange}
|
onCellValueChange={handleCellChange}
|
||||||
|
onCellReferenceClick={handleCellReferenceClick}
|
||||||
|
isInEditMode={isEditing}
|
||||||
stopEditing={stopEditing}
|
stopEditing={stopEditing}
|
||||||
setActiveSheet={setActiveSheet}
|
setActiveSheet={setActiveSheet}
|
||||||
activeCellRef={activeCellInputRef}
|
activeCellRef={activeCellInputRef}
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ export const Spreadsheet = ({
|
|||||||
handleCellClick,
|
handleCellClick,
|
||||||
handleCellDoubleClick,
|
handleCellDoubleClick,
|
||||||
handleCellChange,
|
handleCellChange,
|
||||||
|
handleCellReferenceClick,
|
||||||
|
isInEditMode,
|
||||||
stopEditing,
|
stopEditing,
|
||||||
setActiveSheet,
|
setActiveSheet,
|
||||||
activeCellInputRef,
|
activeCellInputRef,
|
||||||
@@ -46,11 +48,22 @@ export const Spreadsheet = ({
|
|||||||
handleCellClick,
|
handleCellClick,
|
||||||
handleCellDoubleClick,
|
handleCellDoubleClick,
|
||||||
handleCellChange,
|
handleCellChange,
|
||||||
|
handleCellReferenceClick,
|
||||||
|
isInEditMode,
|
||||||
stopEditing,
|
stopEditing,
|
||||||
setActiveSheet,
|
setActiveSheet,
|
||||||
activeCellInputRef,
|
activeCellInputRef,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Отладочное логирование для проверки состояния
|
||||||
|
console.log(`📊 Spreadsheet ${sheetType} состояние:`, {
|
||||||
|
isEditing,
|
||||||
|
isInEditMode,
|
||||||
|
selectedCell,
|
||||||
|
activeSheet,
|
||||||
|
isActiveSheet: activeSheet === sheetType,
|
||||||
|
})
|
||||||
|
|
||||||
const parentRef = useRef<HTMLDivElement>(null)
|
const parentRef = useRef<HTMLDivElement>(null)
|
||||||
const [gridSize, setGridSize] = useState({ width: 0, height: 0 })
|
const [gridSize, setGridSize] = useState({ width: 0, height: 0 })
|
||||||
|
|
||||||
|
|||||||
@@ -56,9 +56,15 @@ export interface CellProps {
|
|||||||
onCellClick: (row: number, col: number) => void
|
onCellClick: (row: number, col: number) => void
|
||||||
onCellDoubleClick: (row: number, col: number) => void
|
onCellDoubleClick: (row: number, col: number) => void
|
||||||
onCellValueChange: (newValue: string) => void // Изменение значения во время редактирования
|
onCellValueChange: (newValue: string) => void // Изменение значения во время редактирования
|
||||||
|
onCellReferenceClick?: (
|
||||||
|
sheetType: SheetType,
|
||||||
|
row: number,
|
||||||
|
col: number
|
||||||
|
) => void // Клик для вставки ссылки
|
||||||
|
isInEditMode: boolean // Глобальный режим редактирования
|
||||||
stopEditing: (save: boolean) => void
|
stopEditing: (save: boolean) => void
|
||||||
setActiveSheet: (type: SheetType) => void
|
setActiveSheet: (type: SheetType) => void
|
||||||
activeCellRef: React.RefObject<HTMLInputElement>
|
activeCellRef: React.RefObject<HTMLInputElement | null>
|
||||||
style: CSSProperties // Добавляем style для react-window
|
style: CSSProperties // Добавляем style для react-window
|
||||||
mergedCellInfo?: {
|
mergedCellInfo?: {
|
||||||
// Информация об объединенных ячейках
|
// Информация об объединенных ячейках
|
||||||
@@ -104,9 +110,15 @@ export interface CellRendererData {
|
|||||||
handleCellClick: (row: number, col: number) => void
|
handleCellClick: (row: number, col: number) => void
|
||||||
handleCellDoubleClick: (row: number, col: number) => void
|
handleCellDoubleClick: (row: number, col: number) => void
|
||||||
handleCellChange: (newValue: string) => void
|
handleCellChange: (newValue: string) => void
|
||||||
|
handleCellReferenceClick?: (
|
||||||
|
sheetType: SheetType,
|
||||||
|
row: number,
|
||||||
|
col: number
|
||||||
|
) => void // Клик для вставки ссылки
|
||||||
|
isInEditMode: boolean // Глобальный режим редактирования
|
||||||
stopEditing: (save: boolean) => void
|
stopEditing: (save: boolean) => void
|
||||||
setActiveSheet: (type: SheetType) => void
|
setActiveSheet: (type: SheetType) => void
|
||||||
activeCellInputRef: React.RefObject<HTMLInputElement>
|
activeCellInputRef: React.RefObject<HTMLInputElement | null>
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CellRendererProps {
|
export interface CellRendererProps {
|
||||||
@@ -129,9 +141,15 @@ export interface SpreadsheetProps {
|
|||||||
handleCellClick: (row: number, col: number) => void
|
handleCellClick: (row: number, col: number) => void
|
||||||
handleCellDoubleClick: (row: number, col: number) => void
|
handleCellDoubleClick: (row: number, col: number) => void
|
||||||
handleCellChange: (newValue: string) => void
|
handleCellChange: (newValue: string) => void
|
||||||
|
handleCellReferenceClick?: (
|
||||||
|
sheetType: SheetType,
|
||||||
|
row: number,
|
||||||
|
col: number
|
||||||
|
) => void // Клик для вставки ссылки
|
||||||
|
isInEditMode: boolean // Глобальный режим редактирования
|
||||||
stopEditing: (save: boolean) => void
|
stopEditing: (save: boolean) => void
|
||||||
setActiveSheet: (type: SheetType) => void
|
setActiveSheet: (type: SheetType) => void
|
||||||
activeCellInputRef: React.RefObject<HTMLInputElement>
|
activeCellInputRef: React.RefObject<HTMLInputElement | null>
|
||||||
containerRefs: React.MutableRefObject<
|
containerRefs: React.MutableRefObject<
|
||||||
Record<SheetType, HTMLDivElement | null>
|
Record<SheetType, HTMLDivElement | null>
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -11,6 +11,22 @@ export function getColumnLabel(index: number): string {
|
|||||||
return label
|
return label
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Создает адрес ячейки из координат (например, A1, B2)
|
||||||
|
export function createCellAddress(row: number, col: number): string {
|
||||||
|
return getColumnLabel(col) + (row + 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Создает квалифицированную ссылку на ячейку с указанием листа
|
||||||
|
export function createQualifiedCellReference(
|
||||||
|
sheetType: 'report' | 'calculations',
|
||||||
|
row: number,
|
||||||
|
col: number
|
||||||
|
): string {
|
||||||
|
const sheetName = sheetType === 'report' ? 'L' : 'R'
|
||||||
|
const cellAddress = createCellAddress(row, col)
|
||||||
|
return `${sheetName}!${cellAddress}`
|
||||||
|
}
|
||||||
|
|
||||||
export function findMergedCellInfo(
|
export function findMergedCellInfo(
|
||||||
row: number,
|
row: number,
|
||||||
col: number,
|
col: number,
|
||||||
|
|||||||
Reference in New Issue
Block a user