From 2a18de765e362dc28328dba8f873465ea08837f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E7=86=B1?= Date: Fri, 26 Jun 2026 16:13:17 +0800 Subject: [PATCH] perf: remove redundant collection scans (#7159) --- .github/workflows/deploy-pr-preview.yml | 43 +++++++-- packages/core/src/shared/ref-alias.ts | 2 +- packages/core/src/shared/tools.ts | 15 ++-- .../controllers/doc-auto-format.controller.ts | 18 ++-- .../src/functions/base-function.ts | 10 ++- .../src/functions/text/textafter/index.ts | 32 ++++--- .../src/functions/text/textbefore/index.ts | 32 ++++--- .../layout/block/paragraph/linebreaking.ts | 11 ++- .../src/controllers/cf.render.controller.ts | 22 ++++- .../sheets-filter-ui/src/models/conditions.ts | 3 +- .../SheetsFilterByConditionsPanel.tsx | 90 +++++++++++++++---- .../controllers/defined-name.controller.ts | 19 ++-- packages/sheets-numfmt/src/utils/mutation.ts | 16 ++-- .../sheet.render-controller.ts | 2 +- .../src/views/defined-name/DefinedName.tsx | 2 +- .../defined-name/DefinedNameContainer.tsx | 2 +- .../views/defined-name/DefinedNameOverlay.tsx | 2 +- packages/sheets/src/facade/f-defined-name.ts | 2 +- 18 files changed, 235 insertions(+), 88 deletions(-) diff --git a/.github/workflows/deploy-pr-preview.yml b/.github/workflows/deploy-pr-preview.yml index 8ff34c99b2..a82a2c5f34 100644 --- a/.github/workflows/deploy-pr-preview.yml +++ b/.github/workflows/deploy-pr-preview.yml @@ -104,13 +104,16 @@ jobs: body: | ## View Deployment - [#${{ github.run_id }}](https://github.com/dream-num/univer/actions/runs/${{ github.run_id }}) + ```txt + status : provisioning preview + target : pr-${{ needs.setup.outputs.id }} + ref : ${{ needs.setup.outputs.ref }} + run : #${{ github.run_id }} + ``` -

- ๐Ÿฅ ๐Ÿ” ๐Ÿฅ“ ๐Ÿฅ— ๐Ÿฅ˜ ๐ŸŒฏ ๐Ÿš ๐Ÿ› ๐Ÿ– ๐Ÿญ ๐Ÿง ๐Ÿ ๐Ÿฅช ๐Ÿฅ– ๐Ÿช
- Still cooking, please come back later
- ๐Ÿฅ™ ๐Ÿฅฎ ๐Ÿฅจ ๐ŸŒญ ๐Ÿฆ ๐Ÿ™ ๐Ÿ• ๐Ÿฐ ๐Ÿฎ ๐Ÿœ ๐Ÿก ๐Ÿฑ ๐Ÿฟ ๐Ÿ• ๐ŸฅŸ -

+ Preview assets are building. This comment will update with deployment links when the preview is ready. + + [Open workflow run](https://github.com/dream-num/univer/actions/runs/${{ github.run_id }}) edit-mode: replace build-and-deploy: @@ -181,6 +184,7 @@ jobs: # ================= Deploy PR Preview ================= - name: ๐Ÿš€ Deploy to GitHub Pages (preview) + id: preview_deploy uses: rossjrw/pr-preview-action@v1 with: source-dir: ./dist @@ -189,3 +193,30 @@ jobs: pr-number: ${{ needs.setup.outputs.id }} comment: false action: ${{ needs.setup.outputs.state == 'closed' && 'remove' || 'deploy' }} + + - name: ๐Ÿงฝ Find deployment comment + uses: peter-evans/find-comment@v4 + if: ${{ needs.setup.outputs.state != 'closed' && steps.preview_deploy.outputs['deployment-action'] == 'deploy' }} + id: preview-comment + with: + issue-number: ${{ needs.setup.outputs.id }} + comment-author: 'github-actions[bot]' + body-includes: View Deployment + + - name: ๐Ÿ“ Update deployment comment + uses: peter-evans/create-or-update-comment@v5 + if: ${{ needs.setup.outputs.state != 'closed' && steps.preview_deploy.outputs['deployment-action'] == 'deploy' }} + with: + comment-id: ${{ steps.preview-comment.outputs.comment-id }} + issue-number: ${{ needs.setup.outputs.id }} + body: | + ## View Deployment + + [Preview](${{ steps.preview_deploy.outputs['preview-url'] }}) ยท [#${{ github.run_id }}](https://github.com/dream-num/univer/actions/runs/${{ github.run_id }}) + + | Entry | Link | + | --- | --- | + | Demo | ${{ steps.preview_deploy.outputs['preview-url'] }} | + | React 16 Demo | ${{ steps.preview_deploy.outputs['preview-url'] }}react16/ | + | Storybook | ${{ steps.preview_deploy.outputs['preview-url'] }}storybook/ | + edit-mode: replace diff --git a/packages/core/src/shared/ref-alias.ts b/packages/core/src/shared/ref-alias.ts index a317527fc0..97870fce99 100644 --- a/packages/core/src/shared/ref-alias.ts +++ b/packages/core/src/shared/ref-alias.ts @@ -72,7 +72,7 @@ export class RefAlias, K extends keyof T = key setValue(key: string, attr: keyof T, value: unknown) { const item = this.getValue(key); if (item) { - if (Object.keys(item).includes(attr as string)) { + if (Object.prototype.hasOwnProperty.call(item, attr)) { item[attr] = value as T[keyof T]; } } diff --git a/packages/core/src/shared/tools.ts b/packages/core/src/shared/tools.ts index 21e6061af0..9f132ee6af 100644 --- a/packages/core/src/shared/tools.ts +++ b/packages/core/src/shared/tools.ts @@ -61,12 +61,11 @@ function diffArrays(oneArray: any[], twoArray: any[]) { function diffObject(oneObject: Record, twoObject: Record) { const oneKeys = Object.keys(oneObject); - const twoKeys = Object.keys(twoObject); - if (oneKeys.length !== twoKeys.length) { + if (oneKeys.length !== Object.keys(twoObject).length) { return false; } for (const key of oneKeys) { - if (!twoKeys.includes(key)) { + if (!Object.prototype.propertyIsEnumerable.call(twoObject, key)) { return false; } const oneValue = oneObject[key]; @@ -271,11 +270,13 @@ export class Tools { return clone as T; } if (this.isObject(value)) { + const source = value as Record; const clone: Record = {}; - Object.keys(value as Record).forEach((key) => { - const item = (value as Record)[key]; - clone[key] = Tools.deepClone(item); - }); + for (const key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) { + clone[key] = Tools.deepClone(source[key]); + } + } Object.setPrototypeOf(clone, Object.getPrototypeOf(value)); return clone as T; } diff --git a/packages/docs-ui/src/controllers/doc-auto-format.controller.ts b/packages/docs-ui/src/controllers/doc-auto-format.controller.ts index a853d4d7a0..afae1c0252 100644 --- a/packages/docs-ui/src/controllers/doc-auto-format.controller.ts +++ b/packages/docs-ui/src/controllers/doc-auto-format.controller.ts @@ -32,6 +32,14 @@ import { DocTableTabCommand } from '../commands/commands/table/doc-table-tab.com import { DocAutoFormatService } from '../services/doc-auto-format.service'; import { isInSameTableCellData } from '../services/selection/convert-rect-range'; +function hasQuickListType(text: string): text is keyof typeof QuickListTypeMap { + return Object.prototype.hasOwnProperty.call(QuickListTypeMap, text); +} + +function hasQuickHeading(text: string): text is keyof typeof QUICK_HEADING_MAP { + return Object.prototype.hasOwnProperty.call(QUICK_HEADING_MAP, text); +} + export class DocAutoFormatController extends Disposable { constructor( @Inject(DocAutoFormatService) private readonly _docAutoFormatService: DocAutoFormatService, @@ -137,7 +145,7 @@ export class DocAutoFormatController extends Disposable { return false; } const text = unit.getBody()?.dataStream.slice(paragraphs[0].paragraphStart, selection.startOffset - 1); - if (text && (Object.keys(QuickListTypeMap).includes(text) || Object.keys(QUICK_HEADING_MAP).includes(text))) { + if (text && (hasQuickListType(text) || hasQuickHeading(text))) { return true; } return false; @@ -145,8 +153,8 @@ export class DocAutoFormatController extends Disposable { getMutations(context) { const { paragraphs, unit, selection } = context; const text = unit.getBody()?.dataStream.slice(paragraphs[0].paragraphStart, selection.startOffset - 1); - if (text && Object.keys(QuickListTypeMap).includes(text)) { - const type = QuickListTypeMap[text as keyof typeof QuickListTypeMap]; + if (text && hasQuickListType(text)) { + const type = QuickListTypeMap[text]; return [{ id: QuickListCommand.id, params: { @@ -156,8 +164,8 @@ export class DocAutoFormatController extends Disposable { }]; } - if (text && Object.keys(QUICK_HEADING_MAP).includes(text)) { - const type = QUICK_HEADING_MAP[text as keyof typeof QUICK_HEADING_MAP]; + if (text && hasQuickHeading(text)) { + const type = QUICK_HEADING_MAP[text]; return [{ id: QuickHeadingCommand.id, params: { diff --git a/packages/engine-formula/src/functions/base-function.ts b/packages/engine-formula/src/functions/base-function.ts index 4adfbbc802..0edac377f4 100644 --- a/packages/engine-formula/src/functions/base-function.ts +++ b/packages/engine-formula/src/functions/base-function.ts @@ -16,7 +16,11 @@ import type { IRange, LocaleType, Nullable } from '@univerjs/core'; import type { IFunctionNames } from '../basics/function'; -import type { BaseReferenceObject, FunctionVariantType, NodeValueType } from '../engine/reference-object/base-reference-object'; +import type { + BaseReferenceObject, + FunctionVariantType, + NodeValueType, +} from '../engine/reference-object/base-reference-object'; import type { ArrayBinarySearchType } from '../engine/utils/compare'; import type { ArrayValueObject } from '../engine/value-object/array-value-object'; import type { BaseValueObject } from '../engine/value-object/base-value-object'; @@ -134,9 +138,9 @@ export class BaseFunction { if (nameMap == null) { return null; } - return Array.from(Object.values(nameMap)).filter((value) => { + return Object.values(nameMap).find((value) => { return value.name === name; - })?.[0]; + }); } setDefinedNames(definedNames: IDefinedNameMapItem) { diff --git a/packages/engine-formula/src/functions/text/textafter/index.ts b/packages/engine-formula/src/functions/text/textafter/index.ts index 51efc2e11c..f55f0151a9 100644 --- a/packages/engine-formula/src/functions/text/textafter/index.ts +++ b/packages/engine-formula/src/functions/text/textafter/index.ts @@ -239,12 +239,16 @@ export class Textafter extends BaseFunction { for (let i = 0; i < Math.abs(instanceNumValue); i++) { if (instanceNumValue < 0) { - const delimiterItem = _delimiterValue.map((item) => { - return { - index: substrText.lastIndexOf(item), - length: item.length, - }; - }).filter((item) => item.index !== -1).sort((a, b) => b.index - a.index)[0]; + let delimiterItem: { index: number; length: number } | undefined; + for (const item of _delimiterValue) { + const index = substrText.lastIndexOf(item); + if (index !== -1 && (!delimiterItem || index > delimiterItem.index)) { + delimiterItem = { + index, + length: item.length, + }; + } + } if (!delimiterItem) { break; @@ -255,12 +259,16 @@ export class Textafter extends BaseFunction { preDelimiterLength = delimiterItem.length; matchNum++; } else { - const delimiterItem = _delimiterValue.map((item) => { - return { - index: substrText.indexOf(item), - length: item.length, - }; - }).filter((item) => item.index !== -1).sort((a, b) => a.index - b.index)[0]; + let delimiterItem: { index: number; length: number } | undefined; + for (const item of _delimiterValue) { + const index = substrText.indexOf(item); + if (index !== -1 && (!delimiterItem || index < delimiterItem.index)) { + delimiterItem = { + index, + length: item.length, + }; + } + } if (!delimiterItem) { break; diff --git a/packages/engine-formula/src/functions/text/textbefore/index.ts b/packages/engine-formula/src/functions/text/textbefore/index.ts index 00e6c65681..b8d0905f68 100644 --- a/packages/engine-formula/src/functions/text/textbefore/index.ts +++ b/packages/engine-formula/src/functions/text/textbefore/index.ts @@ -239,12 +239,16 @@ export class Textbefore extends BaseFunction { for (let i = 0; i < Math.abs(instanceNumValue); i++) { if (instanceNumValue < 0) { - const delimiterItem = _delimiterValue.map((item) => { - return { - index: substrText.lastIndexOf(item), - length: item.length, - }; - }).filter((item) => item.index !== -1).sort((a, b) => b.index - a.index)[0]; + let delimiterItem: { index: number; length: number } | undefined; + for (const item of _delimiterValue) { + const index = substrText.lastIndexOf(item); + if (index !== -1 && (!delimiterItem || index > delimiterItem.index)) { + delimiterItem = { + index, + length: item.length, + }; + } + } if (!delimiterItem) { break; @@ -254,12 +258,16 @@ export class Textbefore extends BaseFunction { substrText = substrText.substr(0, delimiterItem.index); matchNum++; } else { - const delimiterItem = _delimiterValue.map((item) => { - return { - index: substrText.indexOf(item), - length: item.length, - }; - }).filter((item) => item.index !== -1).sort((a, b) => a.index - b.index)[0]; + let delimiterItem: { index: number; length: number } | undefined; + for (const item of _delimiterValue) { + const index = substrText.indexOf(item); + if (index !== -1 && (!delimiterItem || index < delimiterItem.index)) { + delimiterItem = { + index, + length: item.length, + }; + } + } if (!delimiterItem) { break; diff --git a/packages/engine-render/src/components/docs/layout/block/paragraph/linebreaking.ts b/packages/engine-render/src/components/docs/layout/block/paragraph/linebreaking.ts index 59cc9286df..67e69f46c9 100644 --- a/packages/engine-render/src/components/docs/layout/block/paragraph/linebreaking.ts +++ b/packages/engine-render/src/components/docs/layout/block/paragraph/linebreaking.ts @@ -177,9 +177,14 @@ function _withMinSpacing(style: IParagraphStyle, key: 'spaceAbove' | 'spaceBelow } function _getNextAdjacentBlockRange(blockRanges: IDocumentBody['blockRanges'], blockRange: NonNullable[number]) { - return blockRanges - ?.filter((range) => range.startIndex > blockRange.endIndex) - .sort((left, right) => left.startIndex - right.startIndex)[0]; + let nextBlockRange: NonNullable[number] | undefined; + for (const range of blockRanges ?? []) { + if (range.startIndex > blockRange.endIndex && (!nextBlockRange || range.startIndex < nextBlockRange.startIndex)) { + nextBlockRange = range; + } + } + + return nextBlockRange; } function _hasNextAdjacentLayoutBlockRange(blockRanges: IDocumentBody['blockRanges'], blockRange: NonNullable[number]): boolean { diff --git a/packages/sheets-conditional-formatting-ui/src/controllers/cf.render.controller.ts b/packages/sheets-conditional-formatting-ui/src/controllers/cf.render.controller.ts index 200a5cdcab..81a1503fec 100644 --- a/packages/sheets-conditional-formatting-ui/src/controllers/cf.render.controller.ts +++ b/packages/sheets-conditional-formatting-ui/src/controllers/cf.render.controller.ts @@ -20,7 +20,9 @@ import { Disposable, Inject, InterceptorEffectEnum, IUniverInstanceService, Univ import { IRenderManagerService } from '@univerjs/engine-render'; import { INTERCEPTOR_POINT, SheetInterceptorService } from '@univerjs/sheets'; import { ConditionalFormattingRuleModel, ConditionalFormattingService, ConditionalFormattingViewModel, DEFAULT_PADDING, DEFAULT_WIDTH } from '@univerjs/sheets-conditional-formatting'; -import { SheetSkeletonManagerService } from '@univerjs/sheets-ui'; +import { + SheetSkeletonManagerService, +} from '@univerjs/sheets-ui'; import { merge } from 'rxjs'; import { bufferTime, filter } from 'rxjs/operators'; @@ -29,8 +31,20 @@ export class SheetsCfRenderController extends Disposable { * When a set operation is triggered multiple times over a short period of time, it may result in some callbacks not being disposed,and caused a render cache exception. * The solution here is to store all the asynchronous tasks and focus on processing after the last callback */ - private _ruleChangeCacheMap: Map boolean }>> = new Map(); - constructor(@Inject(SheetInterceptorService) private _sheetInterceptorService: SheetInterceptorService, @Inject(ConditionalFormattingService) private _conditionalFormattingService: ConditionalFormattingService, @Inject(IUniverInstanceService) private _univerInstanceService: IUniverInstanceService, @Inject(IRenderManagerService) private _renderManagerService: IRenderManagerService, @Inject(ConditionalFormattingViewModel) private _conditionalFormattingViewModel: ConditionalFormattingViewModel, @Inject(ConditionalFormattingRuleModel) private _conditionalFormattingRuleModel: ConditionalFormattingRuleModel) { + private _ruleChangeCacheMap: Map boolean; + }>> = new Map(); + + constructor( + @Inject(SheetInterceptorService) private _sheetInterceptorService: SheetInterceptorService, + @Inject(ConditionalFormattingService) private _conditionalFormattingService: ConditionalFormattingService, + @Inject(IUniverInstanceService) private _univerInstanceService: IUniverInstanceService, + @Inject(IRenderManagerService) private _renderManagerService: IRenderManagerService, + @Inject(ConditionalFormattingViewModel) private _conditionalFormattingViewModel: ConditionalFormattingViewModel, + @Inject(ConditionalFormattingRuleModel) private _conditionalFormattingRuleModel: ConditionalFormattingRuleModel + ) { super(); this._initViewModelInterceptor(); @@ -58,7 +72,7 @@ export class SheetsCfRenderController extends Disposable { const worksheet = workbook.getActiveSheet(); if (!worksheet) return false; - return v.filter((item) => item.unitId === workbook.getUnitId() && item.subUnitId === worksheet.getSheetId()).length > 0; + return v.some((item) => item.unitId === workbook.getUnitId() && item.subUnitId === worksheet.getSheetId()); }) ).subscribe(() => this._markDirtySkeleton())); } diff --git a/packages/sheets-filter-ui/src/models/conditions.ts b/packages/sheets-filter-ui/src/models/conditions.ts index 6c5fd2a1b6..31b2d46d75 100644 --- a/packages/sheets-filter-ui/src/models/conditions.ts +++ b/packages/sheets-filter-ui/src/models/conditions.ts @@ -16,6 +16,7 @@ import type { Nullable } from '@univerjs/core'; import type { ICustomFilters, IFilterColumn } from '@univerjs/sheets-filter'; +import type { LocaleKey } from '../locale/types'; import { BooleanNumber } from '@univerjs/core'; import { CustomFilterOperator } from '@univerjs/sheets-filter'; import { ExtendCustomFilterOperator, OperatorOrder } from './extended-operators'; @@ -42,7 +43,7 @@ export interface IFilterConditionItem { /** * Name of the filter condition. Should be an i18n key. */ - label: string; + label: LocaleKey; and?: true; diff --git a/packages/sheets-filter-ui/src/views/components/SheetsFilterByConditionsPanel.tsx b/packages/sheets-filter-ui/src/views/components/SheetsFilterByConditionsPanel.tsx index e0a3b92552..41f27db046 100644 --- a/packages/sheets-filter-ui/src/views/components/SheetsFilterByConditionsPanel.tsx +++ b/packages/sheets-filter-ui/src/views/components/SheetsFilterByConditionsPanel.tsx @@ -123,39 +123,90 @@ function usePrimaryOptions(localeService: LocaleService): ISelectProps['options' return useMemo(() => [ { options: [ - { label: localeService.t(FilterConditionItems.NONE.label), value: FilterConditionItems.NONE.operator }, + { + label: localeService.t(FilterConditionItems.NONE.label), + value: FilterConditionItems.NONE.operator, + }, ], }, { options: [ - { label: localeService.t(FilterConditionItems.EMPTY.label), value: FilterConditionItems.EMPTY.operator }, - { label: localeService.t(FilterConditionItems.NOT_EMPTY.label), value: FilterConditionItems.NOT_EMPTY.operator }, + { + label: localeService.t(FilterConditionItems.EMPTY.label), + value: FilterConditionItems.EMPTY.operator, + }, + { + label: localeService.t(FilterConditionItems.NOT_EMPTY.label), + value: FilterConditionItems.NOT_EMPTY.operator, + }, ], }, { options: [ - { label: localeService.t(FilterConditionItems.TEXT_CONTAINS.label), value: FilterConditionItems.TEXT_CONTAINS.operator }, - { label: localeService.t(FilterConditionItems.DOES_NOT_CONTAIN.label), value: FilterConditionItems.DOES_NOT_CONTAIN.operator }, - { label: localeService.t(FilterConditionItems.STARTS_WITH.label), value: FilterConditionItems.STARTS_WITH.operator }, - { label: localeService.t(FilterConditionItems.ENDS_WITH.label), value: FilterConditionItems.ENDS_WITH.operator }, - { label: localeService.t(FilterConditionItems.EQUALS.label), value: FilterConditionItems.EQUALS.operator }, + { + label: localeService.t(FilterConditionItems.TEXT_CONTAINS.label), + value: FilterConditionItems.TEXT_CONTAINS.operator, + }, + { + label: localeService.t(FilterConditionItems.DOES_NOT_CONTAIN.label), + value: FilterConditionItems.DOES_NOT_CONTAIN.operator, + }, + { + label: localeService.t(FilterConditionItems.STARTS_WITH.label), + value: FilterConditionItems.STARTS_WITH.operator, + }, + { + label: localeService.t(FilterConditionItems.ENDS_WITH.label), + value: FilterConditionItems.ENDS_WITH.operator, + }, + { + label: localeService.t(FilterConditionItems.EQUALS.label), + value: FilterConditionItems.EQUALS.operator, + }, ], }, { options: [ - { label: localeService.t(FilterConditionItems.GREATER_THAN.label), value: FilterConditionItems.GREATER_THAN.operator }, - { label: localeService.t(FilterConditionItems.GREATER_THAN_OR_EQUAL.label), value: FilterConditionItems.GREATER_THAN_OR_EQUAL.operator }, - { label: localeService.t(FilterConditionItems.LESS_THAN.label), value: FilterConditionItems.LESS_THAN.operator }, - { label: localeService.t(FilterConditionItems.LESS_THAN_OR_EQUAL.label), value: FilterConditionItems.LESS_THAN_OR_EQUAL.operator }, - { label: localeService.t(FilterConditionItems.EQUAL.label), value: FilterConditionItems.EQUAL.operator }, - { label: localeService.t(FilterConditionItems.NOT_EQUAL.label), value: FilterConditionItems.NOT_EQUAL.operator }, - { label: localeService.t(FilterConditionItems.BETWEEN.label), value: FilterConditionItems.BETWEEN.operator }, - { label: localeService.t(FilterConditionItems.NOT_BETWEEN.label), value: FilterConditionItems.NOT_BETWEEN.operator }, + { + label: localeService.t(FilterConditionItems.GREATER_THAN.label), + value: FilterConditionItems.GREATER_THAN.operator, + }, + { + label: localeService.t(FilterConditionItems.GREATER_THAN_OR_EQUAL.label), + value: FilterConditionItems.GREATER_THAN_OR_EQUAL.operator, + }, + { + label: localeService.t(FilterConditionItems.LESS_THAN.label), + value: FilterConditionItems.LESS_THAN.operator, + }, + { + label: localeService.t(FilterConditionItems.LESS_THAN_OR_EQUAL.label), + value: FilterConditionItems.LESS_THAN_OR_EQUAL.operator, + }, + { + label: localeService.t(FilterConditionItems.EQUAL.label), + value: FilterConditionItems.EQUAL.operator, + }, + { + label: localeService.t(FilterConditionItems.NOT_EQUAL.label), + value: FilterConditionItems.NOT_EQUAL.operator, + }, + { + label: localeService.t(FilterConditionItems.BETWEEN.label), + value: FilterConditionItems.BETWEEN.operator, + }, + { + label: localeService.t(FilterConditionItems.NOT_BETWEEN.label), + value: FilterConditionItems.NOT_BETWEEN.operator, + }, ], }, { options: [ - { label: localeService.t(FilterConditionItems.CUSTOM.label), value: FilterConditionItems.CUSTOM.operator }, + { + label: localeService.t(FilterConditionItems.CUSTOM.label), + value: FilterConditionItems.CUSTOM.operator, + }, ], }, ] as ISelectProps['options'], [locale, localeService]); @@ -166,5 +217,8 @@ function useSecondaryOptions(localeService: LocaleService): ISelectProps['option return useMemo(() => FilterConditionItems.ALL_CONDITIONS .filter((c) => c.numOfParameters !== 2) - .map((c) => ({ label: localeService.t(c.label), value: c.operator })) as ISelectProps['options'], [locale, localeService]); + .map((c) => ({ + label: localeService.t(c.label), + value: c.operator, + })) as ISelectProps['options'], [locale, localeService]); } diff --git a/packages/sheets-formula/src/controllers/defined-name.controller.ts b/packages/sheets-formula/src/controllers/defined-name.controller.ts index 4ca6c2db27..d4794f611c 100644 --- a/packages/sheets-formula/src/controllers/defined-name.controller.ts +++ b/packages/sheets-formula/src/controllers/defined-name.controller.ts @@ -24,8 +24,17 @@ import { toDisposable, UniverInstanceType, } from '@univerjs/core'; -import { FunctionType, IDefinedNamesService, RemoveDefinedNameMutation, SetDefinedNameMutation } from '@univerjs/engine-formula'; -import { getSheetCommandTarget, SCOPE_WORKBOOK_VALUE_DEFINED_NAME, SetWorksheetActiveOperation } from '@univerjs/sheets'; +import { + FunctionType, + IDefinedNamesService, + RemoveDefinedNameMutation, + SetDefinedNameMutation, +} from '@univerjs/engine-formula'; +import { + getSheetCommandTarget, + SCOPE_WORKBOOK_VALUE_DEFINED_NAME, + SetWorksheetActiveOperation, +} from '@univerjs/sheets'; import { IDescriptionService } from '../services/description.service'; /** @@ -177,7 +186,7 @@ export class DefinedNameController extends Disposable { } const functionList: string[] = []; - Array.from(Object.values(definedNames)).forEach((value) => { + Object.values(definedNames).forEach((value) => { const { name } = value; functionList.push(name); }); @@ -202,7 +211,7 @@ export class DefinedNameController extends Disposable { this._preUnitId = _unitId; - Array.from(Object.values(definedNames)).forEach((value) => { + Object.values(definedNames).forEach((value) => { const { name, comment, formulaOrRefString, localSheetId } = value; if (this._descriptionService.hasDescription(name)) { @@ -231,7 +240,7 @@ export class DefinedNameController extends Disposable { const functionList: string[] = []; - Array.from(Object.values(definedNames)).forEach((value) => { + Object.values(definedNames).forEach((value) => { const { name, localSheetId } = value; if (localSheetId !== SCOPE_WORKBOOK_VALUE_DEFINED_NAME && localSheetId !== subUnitId) { functionList.push(name); diff --git a/packages/sheets-numfmt/src/utils/mutation.ts b/packages/sheets-numfmt/src/utils/mutation.ts index 038dbc67ab..65a56ca511 100644 --- a/packages/sheets-numfmt/src/utils/mutation.ts +++ b/packages/sheets-numfmt/src/utils/mutation.ts @@ -44,14 +44,18 @@ export const mergeNumfmtMutations = (list: IMutationInfo[]) => { result.push({ id: RemoveNumfmtMutation.id, params }); } const findKeyFromObj = (obj: Record, item: any) => { - const keys = Object.keys(obj); - const index = keys.findIndex((key) => { + for (const key in obj) { + if (!Object.prototype.hasOwnProperty.call(obj, key)) { + continue; + } const value = obj[key]; - return Tools.diffValue(value, item); - }); - return keys[index]; + if (Tools.diffValue(value, item)) { + return key; + } + } }; if (setMutation[0]) { + let nextIndex = 1; const params = setMutation.reduce( (res, cur) => { Object.keys(cur.values).forEach((key) => { @@ -61,7 +65,7 @@ export const mergeNumfmtMutations = (list: IMutationInfo[]) => { if (index) { res.values[index].ranges.push(...curValue.ranges); } else { - const newIndex = Math.max(...Object.keys(res.refMap).map(Number), 0) + 1; + const newIndex = nextIndex++; res.values[newIndex] = { ranges: curValue.ranges, }; diff --git a/packages/sheets-ui/src/controllers/render-controllers/sheet.render-controller.ts b/packages/sheets-ui/src/controllers/render-controllers/sheet.render-controller.ts index 89d1c80ce0..e43d30d3cb 100644 --- a/packages/sheets-ui/src/controllers/render-controllers/sheet.render-controller.ts +++ b/packages/sheets-ui/src/controllers/render-controllers/sheet.render-controller.ts @@ -115,7 +115,7 @@ export class SheetRenderController extends RxDisposable implements IRenderModule this.disposeWithMe(engine.endFrame$.subscribe(() => { const validRenderInfo = this._renderFrameTimeMetric && - Object.keys(this._renderFrameTimeMetric).filter((key) => key.startsWith(SHEET_EXTENSION_PREFIX)).length > 0; + Object.keys(this._renderFrameTimeMetric).some((key) => key.startsWith(SHEET_EXTENSION_PREFIX)); if (validRenderInfo) { this._afterRenderMetric$.next({ diff --git a/packages/sheets-ui/src/views/defined-name/DefinedName.tsx b/packages/sheets-ui/src/views/defined-name/DefinedName.tsx index 5cee272e2f..2078d09eec 100644 --- a/packages/sheets-ui/src/views/defined-name/DefinedName.tsx +++ b/packages/sheets-ui/src/views/defined-name/DefinedName.tsx @@ -54,7 +54,7 @@ export function DefinedName({ disable }: { disable: boolean }) { const getDefinedNameMap = () => { const definedNameMap = definedNamesService.getDefinedNameMap(unitId); if (definedNameMap) { - return Array.from(Object.values(definedNameMap)); + return Object.values(definedNameMap); } return []; diff --git a/packages/sheets-ui/src/views/defined-name/DefinedNameContainer.tsx b/packages/sheets-ui/src/views/defined-name/DefinedNameContainer.tsx index 62bbabb227..5a4fe2bc20 100644 --- a/packages/sheets-ui/src/views/defined-name/DefinedNameContainer.tsx +++ b/packages/sheets-ui/src/views/defined-name/DefinedNameContainer.tsx @@ -53,7 +53,7 @@ export const DefinedNameContainer = () => { } const definedNameMap = definedNamesService.getDefinedNameMap(unitId); if (definedNameMap) { - return Array.from(Object.values(definedNameMap)); + return Object.values(definedNameMap); } return []; }; diff --git a/packages/sheets-ui/src/views/defined-name/DefinedNameOverlay.tsx b/packages/sheets-ui/src/views/defined-name/DefinedNameOverlay.tsx index 0b21583322..02b79a147f 100644 --- a/packages/sheets-ui/src/views/defined-name/DefinedNameOverlay.tsx +++ b/packages/sheets-ui/src/views/defined-name/DefinedNameOverlay.tsx @@ -39,7 +39,7 @@ export function DefinedNameOverlay({ search, isInputEvent }: { search: string; i const getDefinedNameMap = () => { const definedNameMap = definedNamesService.getDefinedNameMap(unitId); if (definedNameMap) { - return Array.from(Object.values(definedNameMap)); + return Object.values(definedNameMap); } return []; }; diff --git a/packages/sheets/src/facade/f-defined-name.ts b/packages/sheets/src/facade/f-defined-name.ts index 82116c5675..289f78b457 100644 --- a/packages/sheets/src/facade/f-defined-name.ts +++ b/packages/sheets/src/facade/f-defined-name.ts @@ -50,7 +50,7 @@ function getDefinedNameFieldName(unitId: string, localeService: LocaleService, d if (definedNameMap == null) { return localeService.t('sheets.definedName.defaultName') + 1; } - const definedNames = Array.from(Object.values(definedNameMap)); + const definedNames = Object.values(definedNameMap); const count = definedNames.length + 1; const name = localeService.t('sheets.definedName.defaultName') + count; if (definedNamesService.getValueByName(unitId, name) == null) {