From 8f05d694c782957071dbae2475a7b7bbdd8deb00 Mon Sep 17 00:00:00 2001 From: gggpound Date: Fri, 7 Feb 2025 16:14:40 +0800 Subject: [PATCH] fix(numfmt): reset cell value type when remove numfmt --- .../commands/commands/set-numfmt.command.ts | 82 +++++++++++++++++-- .../numfmt-cell-content.controller.ts | 31 +++---- packages/sheets/src/index.ts | 1 + .../src/services/numfmt/numfmt.service.ts | 7 -- 4 files changed, 91 insertions(+), 30 deletions(-) diff --git a/packages/sheets-numfmt/src/commands/commands/set-numfmt.command.ts b/packages/sheets-numfmt/src/commands/commands/set-numfmt.command.ts index 27a682240d6..ea975f47fe9 100644 --- a/packages/sheets-numfmt/src/commands/commands/set-numfmt.command.ts +++ b/packages/sheets-numfmt/src/commands/commands/set-numfmt.command.ts @@ -14,27 +14,31 @@ * limitations under the License. */ -import type { IAccessor, ICommand, IMutationInfo } from '@univerjs/core'; +import type { IAccessor, ICommand, IMutationInfo, Nullable } from '@univerjs/core'; import type { FormatType, IRemoveNumfmtMutationParams, ISetCellsNumfmt, ISetNumfmtMutationParams, + ISetRangeValuesMutationParams, } from '@univerjs/sheets'; -import { +import { CellValueType, CommandType, ICommandService, IUndoRedoService, IUniverInstanceService, - sequenceExecute, -} from '@univerjs/core'; + ObjectMatrix, + sequenceExecute } from '@univerjs/core'; +import { DEFAULT_TEXT_FORMAT } from '@univerjs/engine-numfmt'; import { + checkCellValueType, factoryRemoveNumfmtUndoMutation, factorySetNumfmtUndoMutation, getSheetCommandTarget, rangeMerge, RemoveNumfmtMutation, SetNumfmtMutation, + SetRangeValuesMutation, transformCellsToRange, } from '@univerjs/sheets'; @@ -47,6 +51,7 @@ export interface ISetNumfmtCommandParams { export const SetNumfmtCommand: ICommand = { id: 'sheet.command.numfmt.set.numfmt', type: CommandType.COMMAND, + // eslint-disable-next-line max-lines-per-function handler: (accessor: IAccessor, params) => { if (!params) { return false; @@ -59,7 +64,7 @@ export const SetNumfmtCommand: ICommand = { const target = getSheetCommandTarget(univerInstanceService, params); if (!target) return false; - const { unitId, subUnitId } = target; + const { unitId, subUnitId, worksheet } = target; const setCells = params.values.filter((value) => !!value.pattern) as ISetCellsNumfmt; const removeCells = params.values.filter((value) => !value.pattern); const setRedos = transformCellsToRange(unitId, subUnitId, setCells); @@ -73,9 +78,32 @@ export const SetNumfmtCommand: ICommand = { endRow: cell.row, })), }; - const redos: Array> = []; - const undos: Array> = []; + const redos: Array> = []; + const undos: Array> = []; if (setCells.length) { + const setCellTypeObj = setCells.reduce((pre, cur) => { + if (cur.pattern === DEFAULT_TEXT_FORMAT) { + pre.setValue(cur.row, cur.col, { t: CellValueType.STRING }); + } + const cell = worksheet.getCellRaw(cur.row, cur.col); + if (cell) { + const type = checkCellValueType(cell.v); + if (type !== cell.t) { + pre.setValue(cur.row, cur.col, { t: type }); + } + } + return pre; + }, new ObjectMatrix<{ t: Nullable }>()).getMatrix(); + + const undoSetCellTypeObj = new ObjectMatrix<{ t: Nullable }>(); + new ObjectMatrix<{ t: Nullable }>(setCellTypeObj).forValue((row, col) => { + const cell = worksheet.getCellRaw(row, col); + if (cell) { + undoSetCellTypeObj.setValue(row, col, { t: cell.t }); + } else { + undoSetCellTypeObj.setValue(row, col, { t: undefined }); + } + }); Object.keys(setRedos.values).forEach((key) => { const v = setRedos.values[key]; v.ranges = rangeMerge(v.ranges); @@ -87,14 +115,52 @@ export const SetNumfmtCommand: ICommand = { const undo = factorySetNumfmtUndoMutation(accessor, setRedos); undos.push(...undo); } + if (removeCells.length) { removeRedos.ranges = rangeMerge(removeRedos.ranges); + + const setCellTypeObj = removeCells.reduce((pre, cur) => { + const cell = worksheet.getCellRaw(cur.row, cur.col); + if (cell) { + const type = checkCellValueType(cell.v); + if (type !== cell.t) { + pre.setValue(cur.row, cur.col, { t: type }); + } + } + return pre; + }, new ObjectMatrix<{ t: Nullable }>()).getMatrix(); + + const undoSetCellTypeObj = new ObjectMatrix<{ t: Nullable }>(); + new ObjectMatrix<{ t: Nullable }>(setCellTypeObj).forValue((row, col) => { + const cell = worksheet.getCellRaw(row, col); + if (cell) { + undoSetCellTypeObj.setValue(row, col, { t: cell.t }); + } else { + undoSetCellTypeObj.setValue(row, col, { t: undefined }); + } + }); + redos.push({ id: RemoveNumfmtMutation.id, params: removeRedos, + }, { + id: SetRangeValuesMutation.id, + params: { + unitId, + subUnitId, + cellValue: setCellTypeObj, + }, }); const undo = factoryRemoveNumfmtUndoMutation(accessor, removeRedos); - undos.push(...undo); + + undos.push({ + id: SetRangeValuesMutation.id, + params: { + unitId, + subUnitId, + cellValue: undoSetCellTypeObj.getMatrix(), + }, + }, ...undo); } const result = sequenceExecute(redos, commandService).result; diff --git a/packages/sheets-numfmt/src/controllers/numfmt-cell-content.controller.ts b/packages/sheets-numfmt/src/controllers/numfmt-cell-content.controller.ts index 31abd7e50ab..196956979c4 100644 --- a/packages/sheets-numfmt/src/controllers/numfmt-cell-content.controller.ts +++ b/packages/sheets-numfmt/src/controllers/numfmt-cell-content.controller.ts @@ -37,10 +37,16 @@ import { UniverInstanceType, } from '@univerjs/core'; import { DEFAULT_TEXT_FORMAT } from '@univerjs/engine-numfmt'; -import { InterceptCellContentPriority, INTERCEPTOR_POINT, INumfmtService, SetNumfmtMutation, SetRangeValuesMutation, SheetInterceptorService } from '@univerjs/sheets'; +import { checkCellValueType, InterceptCellContentPriority, INTERCEPTOR_POINT, INumfmtService, SetNumfmtMutation, SetRangeValuesMutation, SheetInterceptorService } from '@univerjs/sheets'; import { BehaviorSubject, merge, of, skip, switchMap } from 'rxjs'; import { getPatternPreviewIgnoreGeneral } from '../utils/pattern'; +const TEXT_FORMAT_MARK = { + tl: { + size: 6, + color: '#409f11', + }, +}; export class SheetsNumfmtCellContentController extends Disposable { private _local$ = new BehaviorSubject('en'); public local$ = this._local$.asObservable(); @@ -90,13 +96,6 @@ export class SheetsNumfmtCellContentController extends Disposable { // eslint-disable-next-line max-lines-per-function private _initInterceptorCellContent() { - const TEXT_FORMAT_MARK = { - tl: { - size: 6, - color: '#409f11', - }, - }; - const renderCache = new ObjectMatrix<{ result: ICellData; parameters: string | number }>(); this.disposeWithMe(merge(this._local$, this._localeService.currentLocale$).subscribe(() => { @@ -129,10 +128,17 @@ export class SheetsNumfmtCellContentController extends Disposable { return next(cell); } - // Add error marker to text format number - if (numfmtValue.pattern === DEFAULT_TEXT_FORMAT && originCellValue.v && isRealNum(originCellValue.v)) { + const type = checkCellValueType(originCellValue.v); + // just handle number + if (type !== CellValueType.NUMBER) { + return next(cell); + } + + // Add error marker to text format number + if (numfmtValue.pattern === DEFAULT_TEXT_FORMAT) { return next({ ...cell, + t: CellValueType.STRING, markers: { ...cell?.markers, ...TEXT_FORMAT_MARK, @@ -140,11 +146,6 @@ export class SheetsNumfmtCellContentController extends Disposable { }); } - // just handle number - if (originCellValue.t !== CellValueType.NUMBER || originCellValue.v == null || Number.isNaN(originCellValue.v)) { - return next(cell); - } - let numfmtRes: string = ''; const cache = renderCache.getValue(location.row, location.col); if (cache && cache.parameters === `${originCellValue.v}_${numfmtValue.pattern}`) { diff --git a/packages/sheets/src/index.ts b/packages/sheets/src/index.ts index 2d6bcab7b12..2da3cc89401 100644 --- a/packages/sheets/src/index.ts +++ b/packages/sheets/src/index.ts @@ -105,6 +105,7 @@ export { expandToContinuousRange } from './basics/expand-range'; export { splitRangeText } from './basics/split-range-text'; export type { SplitDelimiterEnum } from './basics/split-range-text'; export { getNextPrimaryCell } from './services/selections/move-active-cell-util'; +export { checkCellValueType } from './basics/cell-type'; export { ExclusiveRangeService, IExclusiveRangeService } from './services/exclusive-range/exclusive-range-service'; diff --git a/packages/sheets/src/services/numfmt/numfmt.service.ts b/packages/sheets/src/services/numfmt/numfmt.service.ts index 95b6b29a422..b351d8c08b3 100644 --- a/packages/sheets/src/services/numfmt/numfmt.service.ts +++ b/packages/sheets/src/services/numfmt/numfmt.service.ts @@ -18,14 +18,12 @@ import type { IRange } from '@univerjs/core'; import type { INumfmtService } from './type'; import { - CellValueType, Disposable, ILogService, IResourceManagerService, IUniverInstanceService, Range, } from '@univerjs/core'; -import { DEFAULT_TEXT_FORMAT } from '@univerjs/engine-numfmt'; export class NumfmtService extends Disposable implements INumfmtService { constructor( @@ -112,11 +110,6 @@ export class NumfmtService extends Disposable implements INumfmtService { const newStyle = { ...oldStyle, n: { pattern: value.pattern } }; const styleId = styles.setValue(newStyle); cell.s = styleId; - - // Setting the text format for a cell will set the CellValueType to text - if (value.pattern === DEFAULT_TEXT_FORMAT) { - cell.t = CellValueType.STRING; - } } }); });