переименования папок

This commit is contained in:
2025-07-21 15:02:10 +03:00
parent d0c79bd334
commit 84f0c9c6aa
72 changed files with 245 additions and 249 deletions

View File

@@ -0,0 +1,196 @@
import { useEffect, useRef, useState } from 'react'
import { VariableSizeGrid } from 'react-window'
import { COL_COUNT, ROW_COUNT, SHEET_NAMES, SpreadsheetProps } from '../types'
import { getColumnLabel } from '../utils'
import { CellRenderer } from './CellRenderer'
// --- Spreadsheet Component ---
export const Spreadsheet = ({
sheetType,
columnWidths,
spreadsheetWidths,
getCachedCellData,
selectedCell,
activeSheet,
isEditing,
editingValue,
handleCellClick,
handleCellDoubleClick,
handleCellChange,
stopEditing,
setActiveSheet,
activeCellInputRef,
containerRefs,
handleKeyDown,
headerRefs,
rowHeaderRefs,
gridRefs,
onGridScroll,
handleColumnResize,
mergedCells,
}: SpreadsheetProps) => {
const widths = columnWidths
const cachedData = getCachedCellData(sheetType)
const itemData = {
sheetType,
widths,
selectedCell,
activeSheet,
isEditing,
editingValue,
cachedData,
mergedCells,
handleCellClick,
handleCellDoubleClick,
handleCellChange,
stopEditing,
setActiveSheet,
activeCellInputRef,
}
const parentRef = useRef<HTMLDivElement>(null)
const [gridSize, setGridSize] = useState({ width: 0, height: 0 })
useEffect(() => {
const parent = parentRef.current
if (!parent) return
const resizeObserver = new ResizeObserver(() => {
const { width, height } = parent.getBoundingClientRect()
const headerHeight =
parent.querySelector('.column-headers')?.clientHeight || 0
setGridSize({ width, height: height - headerHeight })
})
resizeObserver.observe(parent)
return () => resizeObserver.disconnect()
}, [])
return (
<div
ref={parentRef}
className="flex min-w-0 flex-col overflow-hidden"
style={{
flexBasis: `${spreadsheetWidths[SHEET_NAMES[sheetType]] * 100}%`,
transition: 'none',
}}
onClick={() => setActiveSheet(sheetType)}
>
<div
ref={el => (containerRefs.current[sheetType] = el)}
className="flex h-full flex-col overflow-hidden border bg-card shadow-sm"
onKeyDown={handleKeyDown}
tabIndex={0}
>
{/* Spreadsheet Body */}
<div className="flex flex-1">
{/* Row Headers */}
<div className="flex-shrink-0 bg-muted">
<div className="relative flex h-7 w-10 items-center justify-center border-b border-r border-border">
{/* Компактное обозначение листа */}
<div className="absolute inset-0 flex items-end justify-end p-0.5">
<span
className={`flex h-3 w-3 items-center justify-center rounded-sm text-[9px] font-medium text-white ${
sheetType === 'report'
? 'bg-primary/70'
: 'bg-emerald-500/70'
}`}
>
{SHEET_NAMES[sheetType]}
</span>
</div>
</div>
<div
ref={el => (rowHeaderRefs.current[sheetType] = el)}
className="overflow-y-hidden"
style={{ height: gridSize.height }}
>
<div>
{Array.from({ length: ROW_COUNT }).map((_, rowIndex) => {
const isActiveRow =
selectedCell?.row === rowIndex && activeSheet === sheetType
return (
<div
key={rowIndex}
className={`flex h-7 w-10 items-center justify-center border-b border-r border-border text-xs font-medium ${isActiveRow ? 'bg-primary/15 font-medium text-foreground' : 'text-muted-foreground'}`}
>
{rowIndex + 1}
</div>
)
})}
</div>
</div>
</div>
<div className="flex-1 overflow-hidden">
{/* Column Headers */}
<div
ref={el => (headerRefs.current[sheetType] = el)}
className="column-headers overflow-x-hidden"
>
<div className="flex">
{Array.from({ length: COL_COUNT }).map((_, i) => {
const isActiveColumn =
selectedCell?.col === i && activeSheet === sheetType
const handleMouseDown = (e: React.MouseEvent) => {
e.preventDefault()
const startX = e.clientX
const startWidth = widths[i]
const handleMouseMove = (me: MouseEvent) => {
const newWidth = startWidth + (me.clientX - startX)
handleColumnResize(sheetType, i, newWidth)
}
const handleMouseUp = () => {
document.removeEventListener('mousemove', handleMouseMove)
document.removeEventListener('mouseup', handleMouseUp)
}
document.addEventListener('mousemove', handleMouseMove)
document.addEventListener('mouseup', handleMouseUp)
}
return (
<div
key={i}
className={`relative flex h-7 flex-shrink-0 items-center justify-center border-b border-r border-border bg-muted text-center text-xs font-medium ${isActiveColumn ? 'bg-primary/15 font-medium text-foreground' : 'text-muted-foreground'}`}
style={{ width: widths[i] }}
>
{getColumnLabel(i)}
<div
className="resizer absolute right-0 top-0 h-full w-1 cursor-col-resize hover:bg-primary hover:bg-opacity-50"
onMouseDown={handleMouseDown}
/>
</div>
)
})}
</div>
</div>
{/* Grid */}
<div className="min-h-0 flex-1">
<VariableSizeGrid
ref={(el: VariableSizeGrid | null) =>
(gridRefs.current[sheetType] = el)
}
columnCount={COL_COUNT}
rowCount={ROW_COUNT}
columnWidth={(index: number) => widths[index]}
rowHeight={() => 28}
height={gridSize.height}
width={gridSize.width}
itemData={itemData}
overscanColumnCount={20}
overscanRowCount={10}
onScroll={e => onGridScroll(sheetType, e)}
>
{CellRenderer}
</VariableSizeGrid>
</div>
</div>
</div>
</div>
</div>
)
}