Integrate Fortune Sheet spreadsheet editor in StepAnsicht
Some checks failed
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-school (push) Successful in 36s
CI / test-go-edu-search (push) Successful in 31s
CI / test-python-klausur (push) Failing after 2m40s
CI / test-python-agent-core (push) Successful in 32s
CI / test-nodejs-website (push) Successful in 33s
Some checks failed
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-school (push) Successful in 36s
CI / test-go-edu-search (push) Successful in 31s
CI / test-python-klausur (push) Failing after 2m40s
CI / test-python-agent-core (push) Successful in 32s
CI / test-nodejs-website (push) Successful in 33s
Install @fortune-sheet/react (MIT, v1.0.4) as Excel-like spreadsheet component. New SpreadsheetView.tsx converts unified grid data to Fortune Sheet format (celldata, merge config, column/row sizes). StepAnsicht now has Spreadsheet/Grid toggle: - Spreadsheet mode: full Fortune Sheet with toolbar (bold, italic, color, borders, merge cells, text wrap, undo/redo) - Grid mode: existing GridTable for quick editing Box-origin cells get light tinted background in spreadsheet view. Colspan cells converted to Fortune Sheet merge format. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -8,10 +8,17 @@
|
||||
*/
|
||||
|
||||
import { useCallback, useEffect, useRef, useState } from 'react'
|
||||
import dynamic from 'next/dynamic'
|
||||
import { useGridEditor } from '@/components/grid-editor/useGridEditor'
|
||||
import { GridTable } from '@/components/grid-editor/GridTable'
|
||||
import type { GridZone } from '@/components/grid-editor/types'
|
||||
|
||||
// Lazy-load SpreadsheetView (Fortune Sheet, SSR-incompatible)
|
||||
const SpreadsheetView = dynamic(
|
||||
() => import('./SpreadsheetView').then((m) => m.SpreadsheetView),
|
||||
{ ssr: false, loading: () => <div className="py-8 text-center text-sm text-gray-400">Spreadsheet wird geladen...</div> },
|
||||
)
|
||||
|
||||
const KLAUSUR_API = '/klausur-api'
|
||||
|
||||
interface StepAnsichtProps {
|
||||
@@ -35,7 +42,7 @@ export function StepAnsicht({ sessionId, onNext }: StepAnsichtProps) {
|
||||
const [buildError, setBuildError] = useState<string | null>(null)
|
||||
const leftRef = useRef<HTMLDivElement>(null)
|
||||
const [leftHeight, setLeftHeight] = useState(600)
|
||||
const [showGrid, setShowGrid] = useState(false)
|
||||
const [viewMode, setViewMode] = useState<'spreadsheet' | 'grid'>('spreadsheet')
|
||||
|
||||
// Build unified grid
|
||||
const buildUnified = useCallback(async () => {
|
||||
@@ -114,6 +121,20 @@ export function StepAnsicht({ sessionId, onNext }: StepAnsichtProps) {
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="flex rounded-lg overflow-hidden border border-gray-300 dark:border-gray-600">
|
||||
<button
|
||||
onClick={() => setViewMode('spreadsheet')}
|
||||
className={`px-3 py-1.5 text-xs font-medium ${viewMode === 'spreadsheet' ? 'bg-teal-600 text-white' : 'bg-white dark:bg-gray-700 text-gray-600 dark:text-gray-300'}`}
|
||||
>
|
||||
Spreadsheet
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setViewMode('grid')}
|
||||
className={`px-3 py-1.5 text-xs font-medium ${viewMode === 'grid' ? 'bg-teal-600 text-white' : 'bg-white dark:bg-gray-700 text-gray-600 dark:text-gray-300'}`}
|
||||
>
|
||||
Grid
|
||||
</button>
|
||||
</div>
|
||||
<button
|
||||
onClick={buildUnified}
|
||||
disabled={building}
|
||||
@@ -147,36 +168,35 @@ export function StepAnsicht({ sessionId, onNext }: StepAnsichtProps) {
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* RIGHT: Unified Grid Table */}
|
||||
<div className="flex-1 border border-gray-300 dark:border-gray-600 rounded-lg overflow-auto bg-white dark:bg-gray-900" style={{ maxHeight: `${Math.max(600, leftHeight)}px` }}>
|
||||
<div className="px-2 py-1 bg-teal-600/80 text-white text-[10px] font-medium sticky top-0 z-20">
|
||||
Unified Grid
|
||||
{unifiedGrid?.is_unified && (
|
||||
<span className="ml-2 opacity-70">
|
||||
({unifiedGrid.summary?.total_rows}×{unifiedGrid.summary?.total_columns})
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
{unifiedZone ? (
|
||||
<GridTable
|
||||
zone={unifiedZone}
|
||||
selectedCell={selectedCell}
|
||||
selectedCells={selectedCells}
|
||||
onSelectCell={setSelectedCell}
|
||||
onCellTextChange={updateCellText}
|
||||
onToggleColumnBold={toggleColumnBold}
|
||||
onToggleRowHeader={toggleRowHeader}
|
||||
onNavigate={(cellId, dir) => {
|
||||
const next = getAdjacentCell(cellId, dir)
|
||||
if (next) setSelectedCell(next)
|
||||
}}
|
||||
onDeleteColumn={deleteColumn}
|
||||
onAddColumn={addColumn}
|
||||
onDeleteRow={deleteRow}
|
||||
onAddRow={addRow}
|
||||
onToggleCellSelection={toggleCellSelection}
|
||||
onSetCellColor={setCellColor}
|
||||
/>
|
||||
{/* RIGHT: Spreadsheet or Grid view */}
|
||||
<div className="flex-1 border border-gray-300 dark:border-gray-600 rounded-lg overflow-hidden bg-white dark:bg-gray-900" style={{ maxHeight: `${Math.max(700, leftHeight)}px` }}>
|
||||
{viewMode === 'spreadsheet' && unifiedGrid ? (
|
||||
<SpreadsheetView unifiedGrid={unifiedGrid} height={Math.max(650, leftHeight - 10)} />
|
||||
) : viewMode === 'grid' && unifiedZone ? (
|
||||
<div className="overflow-auto h-full">
|
||||
<div className="px-2 py-1 bg-teal-600/80 text-white text-[10px] font-medium sticky top-0 z-20">
|
||||
Grid View ({unifiedGrid?.summary?.total_rows}×{unifiedGrid?.summary?.total_columns})
|
||||
</div>
|
||||
<GridTable
|
||||
zone={unifiedZone}
|
||||
selectedCell={selectedCell}
|
||||
selectedCells={selectedCells}
|
||||
onSelectCell={setSelectedCell}
|
||||
onCellTextChange={updateCellText}
|
||||
onToggleColumnBold={toggleColumnBold}
|
||||
onToggleRowHeader={toggleRowHeader}
|
||||
onNavigate={(cellId, dir) => {
|
||||
const next = getAdjacentCell(cellId, dir)
|
||||
if (next) setSelectedCell(next)
|
||||
}}
|
||||
onDeleteColumn={deleteColumn}
|
||||
onAddColumn={addColumn}
|
||||
onDeleteRow={deleteRow}
|
||||
onAddRow={addRow}
|
||||
onToggleCellSelection={toggleCellSelection}
|
||||
onSetCellColor={setCellColor}
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<div className="p-8 text-center text-gray-400">
|
||||
<p>Kein Unified Grid verfügbar.</p>
|
||||
|
||||
Reference in New Issue
Block a user