Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(sheet): sheet name check #2660

Merged
merged 1 commit into from
Jul 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,6 @@ export { AuthzIoLocalService } from './services/authz-io/authz-io-local.service'
export { IAuthzIoService } from './services/authz-io/type';
export { createDefaultUser } from './services/user-manager/const';
export { skipParseTagNames } from './types/const/clipboard';

export { nameCharacterCheck } from './shared/name';
installShims();

59 changes: 59 additions & 0 deletions packages/core/src/shared/__tests__/name.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/**
* Copyright 2023-present DreamNum Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import { describe, expect, it } from 'vitest';
import { nameCharacterCheck } from '../name';

describe('Test name', () => {
it('Test nameCharacterCheck', () => {
// Test cases
const testNames = [
'', // Invalid: empty string
'Sheet1', // Valid
'Sheet:Name', // Invalid: contains :
'Sheet/Name', // Invalid: contains /
'Sheet\\Name', // Invalid: contains \
'Sheet?Name', // Invalid: contains ?
'Sheet*Name', // Invalid: contains *
'Sheet[Name]', // Invalid: contains [ and ]
'Sheet]Name[', // Invalid: contains ] and [
"'SheetName", // Invalid: starts with '
"SheetName'", // Invalid: ends with '
'ThisSheetNameIsWayTooLongForExcelSheets', // Invalid: more than 31 characters
'ValidSheetName', // Valid
];

const expectedResults = [
false,
true,
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
true,
];

testNames.forEach((name, i) => {
expect(nameCharacterCheck(name)).toBe(expectedResults[i]);
});
});
});
43 changes: 0 additions & 43 deletions packages/core/src/shared/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,49 +168,6 @@ export function isFormulaId(value: any): boolean {
return Tools.isString(value) && value.length > 0;
}

/**
* Convert rich text json to DOM
* @param p
*/
export function handleJsonToDom(p: IDocumentData): string {
// let span = '';
// // let span = `<span id="${p.id}">`;
// if (p.body?.blockElements) {
// for (let k in p.body.blockElements) {
// const section = p.body.blockElements[k];
// if (
// section.blockType !== BlockType.PARAGRAPH &&
// section.blockType !== BlockType.SECTION_BREAK
// ) {
// continue;
// }
// if (section.blockType === BlockType.PARAGRAPH) {
// for (let i in section.paragraph) {
// const element = section.paragraph[i];
// for (let j in element) {
// const item = element[j];
// if (item.et === ParagraphElementType.TEXT_RUN) {
// let style = `display:inline-block;${handleStyleToString(
// item.tr.ts
// )}`;
// span += `<span id='${item.eId}' ${
// style.length ? `style="${style}"` : ''
// } >${item.tr.ct}</span>`;
// }
// }
// }
// }
// // else if (section.blockType === BlockType.SECTION_BREAK) {
// // span += '<br/>';
// // }
// }
// }

// // span += '</span>';
// return span;
return '';
}

/**
* transform style object to string
* @param style
Expand Down
50 changes: 50 additions & 0 deletions packages/core/src/shared/name.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/**
* Copyright 2023-present DreamNum Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**
* The name you entered for the worksheet or chart is invalid. Please ensure:

The name is no more than 31 characters.
The first and last characters cannot be '
The name does not contain any of the following characters: : \ / ? * [ or ].
The name is not empty.
* @param name
* @returns
*/
export function nameCharacterCheck(name: string) {
// Excel sheet name cannot be empty
if (name.length === 0) {
return false;
}

// Excel sheet name cannot exceed 31 characters
if (name.length > 31) {
return false;
}

// Excel sheet name cannot start or end with a single quote
if (name.startsWith("'") || name.endsWith("'")) {
return false;
}

// Excel sheet name cannot contain invalid characters
const invalidChars = /[:\\\/\?\*\[\]]/;
if (invalidChars.test(name)) {
return false;
}

return true;
}
2 changes: 1 addition & 1 deletion packages/sheets-ui/src/locale/en-US.ts
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ const locale: typeof zhCN = {
noHide: "Can't hide, at least keep one sheet tag",
chartEditNoOpt: 'This operation is not allowed in chart editing mode!',
sheetNameErrorTitle: 'There was a problem',
sheetNameSpecCharError: 'The name cannot contain:[ ] : ? * / \' "',
sheetNameSpecCharError: "The name cannot exceed 31 characters, cannot start or end with ', and cannot contain: [ ] : \\ ? * /",
sheetNameCannotIsEmptyError: 'The sheet name cannot be empty.',
sheetNameAlreadyExistsError: 'The sheet name already exists. Please enter another name.',
deleteSheet: 'Delete worksheet',
Expand Down
2 changes: 1 addition & 1 deletion packages/sheets-ui/src/locale/ru-RU.ts
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ const locale: typeof zhCN = {
noHide: 'Нельзя скрыть, оставьте хотя бы одну вкладку листа',
chartEditNoOpt: 'Эта операция недоступна в режиме редактирования диаграммы!',
sheetNameErrorTitle: 'Произошла ошибка',
sheetNameSpecCharError: 'Имя не может содержать: [ ] : ? * / \' "',
sheetNameSpecCharError: "Имя не может превышать 31 символов, начало и конец имени не могут быть ' и имя не может содержать: [ ] : \\ ? * /",
sheetNameCannotIsEmptyError: 'Имя листа не может быть пустым.',
sheetNameAlreadyExistsError: 'Имя листа уже существует. Пожалуйста, введите другое имя.',
deleteSheet: 'Удалить лист',
Expand Down
2 changes: 1 addition & 1 deletion packages/sheets-ui/src/locale/zh-CN.ts
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ const locale = {
noHide: '不能隐藏, 至少保留一个sheet标签',
chartEditNoOpt: '图表编辑模式下不允许该操作!',
sheetNameErrorTitle: '错误',
sheetNameSpecCharError: "名称不能超过31个字符,首尾不能是' 且名称不能包含:\r\n[ ] : \\ ? * /",
sheetNameSpecCharError: "名称不能超过 31 个字符,首尾不能是' 且名称不能包含: [ ] : \\ ? * /",
sheetNameCannotIsEmptyError: '名称不能为空。',
sheetNameAlreadyExistsError: '工作表已存在,请输入其它名称。',
deleteSheet: '删除工作表',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/

import type { ICommandInfo, Workbook } from '@univerjs/core';
import { ICommandService, IPermissionService, IUniverInstanceService, LocaleService, UniverInstanceType } from '@univerjs/core';
import { ICommandService, IPermissionService, IUniverInstanceService, LocaleService, nameCharacterCheck, UniverInstanceType } from '@univerjs/core';
import { Dropdown } from '@univerjs/design';
import {
InsertSheetMutation,
Expand Down Expand Up @@ -180,7 +180,7 @@ export function SheetBarTabs() {
sheetBarService.setScroll(state);
},
onNameCheckAlert: (text: string) => {
return nameEmptyCheck(text) || nameRepeatCheck(text);
return nameEmptyCheck(text) || sheetNameSpecCharCheck(text) || nameRepeatCheck(text);
},
onNameChangeCheck: () => {
const unitId = workbook.getUnitId();
Expand Down Expand Up @@ -232,6 +232,30 @@ export function SheetBarTabs() {
return false;
};

const sheetNameSpecCharCheck = (name: string) => {
if (!nameCharacterCheck(name)) {
const id = 'sheetNameSpecCharAlert';
confirmService.open({
id,
title: { title: localeService.t('sheetConfig.sheetNameErrorTitle') },
children: { title: localeService.t('sheetConfig.sheetNameSpecCharError') },
cancelText: localeService.t('button.cancel'),
confirmText: localeService.t('button.confirm'),
onClose() {
focusTabEditor();
confirmService.close(id);
},
onConfirm() {
focusTabEditor();
confirmService.close(id);
},
});

return true;
}
return false;
};

const nameRepeatCheck = (name: string) => {
const workbook = univerInstanceService.getCurrentUnitForType<Workbook>(UniverInstanceType.UNIVER_SHEET)!;
const worksheet = workbook.getActiveSheet();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ export class SlideTabItem {

const inputAction = (e: Event) => {
if (!input) return;
const maxLength = 50;
const maxLength = 31;

setTimeout(() => {
if (compositionFlag) {
Expand Down
Loading