From c2620611d381ffcfc783f48cafc0da8df1605337 Mon Sep 17 00:00:00 2001 From: ImJeremyHe Date: Sun, 29 Dec 2024 11:08:39 +0800 Subject: [PATCH] fix: sheet tab --- src/components/canvas/component.tsx | 13 ++++++- src/components/canvas/store/render.ts | 15 +++----- src/components/canvas/store/store.ts | 30 +++++++++++++-- src/components/content/index.tsx | 10 ++++- src/components/sheets-tab/index.tsx | 54 +++++++++++++++++++++------ src/core/data2/service.ts | 4 +- 6 files changed, 97 insertions(+), 29 deletions(-) diff --git a/src/components/canvas/component.tsx b/src/components/canvas/component.tsx index 8cb77ae..cac5285 100644 --- a/src/components/canvas/component.tsx +++ b/src/components/canvas/component.tsx @@ -36,6 +36,8 @@ const canvasHost = () => { export interface CanvasProps { selectedCell: SelectedCell selectedCell$: (e: SelectedCell) => void + activeSheet: number + activeSheet$: (s: number) => void } export const CanvasComponent = (props: CanvasProps) => { const DATA_SERVICE = useInjection(TYPES.Data) @@ -47,7 +49,8 @@ export const CanvasComponent = (props: CanvasProps) => { ) } -const Internal: FC = observer(({selectedCell, selectedCell$}) => { +const Internal: FC = observer((props: CanvasProps) => { + const {selectedCell, selectedCell$, activeSheet, activeSheet$} = props const store = useContext(CanvasStoreContext) const [contextmenuOpen, setContextMenuOpen] = useState(false) const [invalidFormulaWarning, setInvalidFormulaWarning] = useState(false) @@ -77,6 +80,12 @@ const Internal: FC = observer(({selectedCell, selectedCell$}) => { store.textarea.reset() }, [selectedCell]) + useEffect(() => { + store.render.canvas.focus() + store.dataSvc.setCurrentSheetIdx(activeSheet) + store.render.render() + }, [activeSheet]) + useEffect(() => { const sub = on(window, EventType.MOUSE_MOVE).subscribe((mme) => { mme.preventDefault() @@ -129,7 +138,7 @@ const Internal: FC = observer(({selectedCell, selectedCell$}) => { const onMouseWheel = (e: WheelEvent) => { // only support y scrollbar currently if (store.anchorY + e.deltaY < 0) return - store.anchorY += e.deltaY + store.setAnchor(store.anchorX, store.anchorY + e.deltaY) const now = Date.now() if (now - lastScrollTime < 50) return diff --git a/src/components/canvas/store/render.ts b/src/components/canvas/store/render.ts index 811b802..ea9e2f7 100644 --- a/src/components/canvas/store/render.ts +++ b/src/components/canvas/store/render.ts @@ -1,13 +1,8 @@ import {makeObservable} from 'mobx' import {CanvasStore} from './store' import {Box, CanvasAttr, PainterService, TextAttr} from '@/core/painter' -import {pxToPt, simpleUuid, toA1notation} from '@/core' -import { - CellViewData, - CellViewRespType, - RenderCell, - toCanvasPosition, -} from '@/core/data2' +import {simpleUuid, toA1notation} from '@/core' +import {CellViewData, RenderCell, toCanvasPosition} from '@/core/data2' import {LeftTop, SETTINGS} from '@/core/settings' import {StandardColor, Range, StandardCell} from '@/core/standable' import {StandardStyle} from '@/core/standable/style' @@ -71,8 +66,10 @@ export class Render { if (!data) return const firstRow = data.rows[0] const firstCol = data.cols[0] - this.store.anchorY = firstRow.position.startRow - this.store.anchorX = firstCol.position.startCol + this.store.setAnchor( + firstRow.position.startRow, + firstCol.position.startCol + ) this.render() }) } diff --git a/src/components/canvas/store/store.ts b/src/components/canvas/store/store.ts index 532d238..361d382 100644 --- a/src/components/canvas/store/store.ts +++ b/src/components/canvas/store/store.ts @@ -31,10 +31,7 @@ export class CanvasStore { * left mousedown the same cell */ same = false - currSheetIdx = 0 - anchorX = 0 - anchorY = 0 render: Render resizer: Resizer highlights: Highlights @@ -43,6 +40,28 @@ export class CanvasStore { scrollbar: ScrollBar textarea: Textarea + get currSheetIdx() { + return this.dataSvc.getCurrentSheetIdx() + } + + get anchorX() { + return this._sheetAnchorData.get(this.currSheetIdx)?.anchorX ?? 0 + } + + get anchorY() { + return this._sheetAnchorData.get(this.currSheetIdx)?.anchorY ?? 0 + } + + setAnchor(x: number, y: number) { + const data = this._sheetAnchorData.get(this.currSheetIdx) ?? { + anchorX: 0, + anchorY: 0, + } + data.anchorX = x + data.anchorY = y + this._sheetAnchorData.set(this.currSheetIdx, data) + } + getCurrentCellView(): readonly CellViewData[] { return this.dataSvc.getCurrentCellView(this.currSheetIdx) } @@ -129,6 +148,11 @@ export class CanvasStore { this.same = true this.selector.onScroll(newStartCell) } + + private _sheetAnchorData = new Map< + number, + {anchorX: number; anchorY: number} + >() } // @ts-expect-error init data when use diff --git a/src/components/content/index.tsx b/src/components/content/index.tsx index 04bba3c..0f79985 100644 --- a/src/components/content/index.tsx +++ b/src/components/content/index.tsx @@ -1,5 +1,5 @@ import {SelectedCell, CanvasComponent} from '@/components/canvas' -import {FC} from 'react' +import {FC, useState} from 'react' import styles from './content.module.scss' import {EditBarComponent} from './edit-bar' import {SheetsTabComponent} from '@/components/sheets-tab' @@ -13,6 +13,7 @@ export const ContentComponent: FC = ({ selectedCell$, selectedCell, }) => { + const [activeSheet, activeSheet$] = useState(0) return (
= ({
- + ) } diff --git a/src/components/sheets-tab/index.tsx b/src/components/sheets-tab/index.tsx index 22578c9..ad1b772 100644 --- a/src/components/sheets-tab/index.tsx +++ b/src/components/sheets-tab/index.tsx @@ -13,9 +13,15 @@ import {Tabs} from 'antd' import {Subscription} from 'rxjs' import {DataService} from '@/core/data2' -export type SheetsTabprops = Record +export interface SheetTabProps { + activeSheet: number + activeSheet$: (s: number) => void +} -export const SheetsTabComponent: FC = () => { +export const SheetsTabComponent: FC = ({ + activeSheet, + activeSheet$, +}) => { const DATA_SERVICE = useInjection(TYPES.Data) const getSheets = () => { const sheetInfo = DATA_SERVICE.getAllSheetInfo().then((info) => { @@ -24,9 +30,14 @@ export const SheetsTabComponent: FC = () => { return sheetInfo } const [sheets, setSheets] = useState([] as string[]) - const [active, setActive] = useState(0) const [isOpen, setIsOpen] = useState(false) + useEffect(() => { + getSheets().then((v) => { + if (v) setSheets(v) + }) + }, []) + useEffect(() => { const subs = new Subscription() subs.add( @@ -43,12 +54,12 @@ export const SheetsTabComponent: FC = () => { const onTabChange = (key: string) => { const i = sheets.findIndex((s) => s === key) - setActive(i) - DATA_SERVICE.setCurrentSheetIDx(i) + activeSheet$(i) + DATA_SERVICE.setCurrentSheetIdx(i) } const add = () => { - const payload = new InsertSheetBuilder().sheetIdx(active).build() + const payload = new InsertSheetBuilder().sheetIdx(activeSheet).build() DATA_SERVICE.handleTransaction(new Transaction([payload], true)) } @@ -69,7 +80,7 @@ export const SheetsTabComponent: FC = () => { onContextMenu={(e) => { e.preventDefault() e.stopPropagation() - setActive(i) + activeSheet$(i) setIsOpen(true) }} > @@ -81,26 +92,47 @@ export const SheetsTabComponent: FC = () => { onChange={onTabChange} onEdit={(e, action) => { if (action === 'add') { + const newSheetName = findNewSheetName(sheets) + const newIdx = sheets.length const payload = new InsertSheetBuilder() - .sheetIdx(sheets.length) + .name(newSheetName) + .sheetIdx(newIdx) .build() DATA_SERVICE.handleTransaction( new Transaction([payload], true) - ) + ).then((v) => { + if (isErrorMessage(v)) return + activeSheet$(newIdx) + }) } else if (action === 'remove') { if (typeof e !== 'string') return const i = sheets.findIndex((s) => s === e) onDelete(i) } }} - activeKey={sheets[active]} + activeKey={sheets[activeSheet]} /> ) } + +function findNewSheetName(sheetNames: readonly string[]): string { + const sheetPattern = /^Sheet(\d+)$/ + + const numbers = sheetNames + .map((name) => { + const match = name.match(sheetPattern) + return match ? parseInt(match[1], 10) : null + }) + .filter((num): num is number => num !== null) + + const nextNumber = numbers.length > 0 ? Math.max(...numbers) + 1 : 1 + + return `Sheet${nextNumber}` +} diff --git a/src/core/data2/service.ts b/src/core/data2/service.ts index 3b0a9ad..5e1b703 100644 --- a/src/core/data2/service.ts +++ b/src/core/data2/service.ts @@ -53,7 +53,7 @@ export interface DataService { getCurrentCellView(sheetIdx: number): readonly CellViewData[] getCurrentSheetIdx(): number - setCurrentSheetIDx(idx: number): void + setCurrentSheetIdx(idx: number): void getAllSheetInfo(): Resp getCellInfo(sheetIdx: number, row: number, col: number): Resp @@ -104,7 +104,7 @@ export class DataServiceImpl implements DataService { return this._sheetIdx } - public setCurrentSheetIDx(idx: number): void { + public setCurrentSheetIdx(idx: number): void { this._sheetIdx = idx }