chore: replace all cn comments of fe to en version by volc api (#320)
This commit is contained in:
@@ -22,7 +22,7 @@ import { render, screen, fireEvent } from '@testing-library/react';
|
||||
import '@testing-library/jest-dom';
|
||||
import { ImageRender } from '../../../src/components/renders/image-render';
|
||||
|
||||
// 模拟依赖
|
||||
// simulated dependency
|
||||
vi.mock('@coze-arch/bot-semi', () => ({
|
||||
Image: ({ src, fallback, placeholder, onClick, preview, ...props }: any) => {
|
||||
if (!src) {
|
||||
@@ -55,7 +55,7 @@ vi.mock('@coze-arch/bot-icons', () => ({
|
||||
),
|
||||
}));
|
||||
|
||||
// 模拟useImagePreview钩子
|
||||
// Simulation useImagePreview hook
|
||||
vi.mock(
|
||||
'../../../src/components/renders/image-render/use-image-preview',
|
||||
() => ({
|
||||
@@ -84,7 +84,7 @@ describe('ImageRender', () => {
|
||||
|
||||
render(<ImageRender srcList={srcList} />);
|
||||
|
||||
// 验证图片容器被渲染
|
||||
// Verify that the image container is rendered
|
||||
const images = screen.getAllByTestId('image');
|
||||
expect(images).toHaveLength(2);
|
||||
expect(images[0]).toHaveAttribute('src', srcList[0]);
|
||||
@@ -94,11 +94,11 @@ describe('ImageRender', () => {
|
||||
test('应该处理空的图片列表', () => {
|
||||
render(<ImageRender srcList={[]} />);
|
||||
|
||||
// 验证没有图片被渲染
|
||||
// Verify that no images are being rendered
|
||||
const images = screen.queryAllByTestId('image');
|
||||
expect(images).toHaveLength(0);
|
||||
|
||||
// 验证空状态容器存在
|
||||
// Verify that an empty state container exists
|
||||
const emptyContainer = screen.getByTestId('image-preview-modal');
|
||||
expect(emptyContainer).toBeInTheDocument();
|
||||
});
|
||||
@@ -112,7 +112,7 @@ describe('ImageRender', () => {
|
||||
|
||||
render(<ImageRender srcList={[]} customEmpty={customEmpty} />);
|
||||
|
||||
// 验证自定义空状态被渲染
|
||||
// Verify that the custom empty state is rendered
|
||||
const customEmptyElement = screen.getByTestId('custom-empty');
|
||||
expect(customEmptyElement).toBeInTheDocument();
|
||||
expect(customEmptyElement).toHaveTextContent('自定义空状态');
|
||||
@@ -126,8 +126,8 @@ describe('ImageRender', () => {
|
||||
/>,
|
||||
);
|
||||
|
||||
// 验证自定义className被应用
|
||||
// 由于组件结构复杂,我们直接查找包含custom-class的元素
|
||||
// Verify that the custom className is applied
|
||||
// Due to the complex structure of components, we directly look for elements containing custom-classes
|
||||
const container = document.querySelector('.custom-class');
|
||||
expect(container).toBeInTheDocument();
|
||||
});
|
||||
@@ -137,11 +137,11 @@ describe('ImageRender', () => {
|
||||
|
||||
render(<ImageRender srcList={srcList} />);
|
||||
|
||||
// 点击图片
|
||||
// Click on the picture.
|
||||
const image = screen.getByTestId('image');
|
||||
fireEvent.click(image);
|
||||
|
||||
// 验证预览模态框存在
|
||||
// Verify that the preview modal box exists
|
||||
const previewModal = screen.getByTestId('image-preview-modal');
|
||||
expect(previewModal).toBeInTheDocument();
|
||||
expect(previewModal).toHaveAttribute('data-src', srcList[0]);
|
||||
@@ -155,7 +155,7 @@ describe('ImageRender', () => {
|
||||
/>,
|
||||
);
|
||||
|
||||
// 验证editable属性被传递给预览模态框
|
||||
// Verify that the editable property is passed to the preview modal box
|
||||
const previewModal = screen.getByTestId('image-preview-modal');
|
||||
expect(previewModal).toHaveAttribute('data-editable', 'false');
|
||||
});
|
||||
@@ -169,7 +169,7 @@ describe('ImageRender', () => {
|
||||
/>,
|
||||
);
|
||||
|
||||
// 验证onChange属性被传递给预览模态框
|
||||
// Verify that the onChange property is passed to the preview modal box
|
||||
const previewModal = screen.getByTestId('image-preview-modal');
|
||||
expect(previewModal).toBeInTheDocument();
|
||||
});
|
||||
|
||||
@@ -22,7 +22,7 @@ import { render, screen, fireEvent } from '@testing-library/react';
|
||||
import '@testing-library/jest-dom';
|
||||
import { useImagePreview } from '../../../src/components/renders/image-render/use-image-preview';
|
||||
|
||||
// 模拟依赖
|
||||
// simulated dependency
|
||||
vi.mock('@coze-arch/coze-design', () => ({
|
||||
Upload: function Upload({
|
||||
children,
|
||||
@@ -167,7 +167,7 @@ vi.mock('../../../src/components/renders/image-render/utils', () => ({
|
||||
isValidSize: vi.fn().mockReturnValue(true),
|
||||
}));
|
||||
|
||||
// 模拟 CustomError
|
||||
// Simulate CustomError
|
||||
vi.mock('@coze-arch/bot-error', () => ({
|
||||
CustomError: class CustomError extends Error {
|
||||
constructor(event: string, message: string) {
|
||||
@@ -179,7 +179,7 @@ vi.mock('@coze-arch/bot-error', () => ({
|
||||
|
||||
describe('useImagePreview 基本功能测试', () => {
|
||||
test('测试图片URL输入框更新', () => {
|
||||
// 创建一个简单的测试组件
|
||||
// Create a simple test component
|
||||
const TestComponent = () => {
|
||||
const [src, setSrc] = React.useState('https://example.com/image.jpg');
|
||||
const onChange = vi.fn();
|
||||
@@ -201,16 +201,16 @@ describe('useImagePreview 基本功能测试', () => {
|
||||
|
||||
render(<TestComponent />);
|
||||
|
||||
// 验证初始URL正确显示
|
||||
// Verify that the initial URL is displayed correctly
|
||||
const urlInput = screen.getByTestId('image-url-input');
|
||||
expect(urlInput).toHaveValue('https://example.com/image.jpg');
|
||||
|
||||
// 修改URL
|
||||
// Modify URL
|
||||
fireEvent.change(urlInput, {
|
||||
target: { value: 'https://example.com/new-image.jpg' },
|
||||
});
|
||||
|
||||
// 验证URL已更新
|
||||
// Verify that the URL has been updated
|
||||
expect(
|
||||
screen.getByText('当前图片URL: https://example.com/new-image.jpg'),
|
||||
).toBeInTheDocument();
|
||||
@@ -219,7 +219,7 @@ describe('useImagePreview 基本功能测试', () => {
|
||||
test('测试确认按钮调用onChange', () => {
|
||||
const onChange = vi.fn();
|
||||
|
||||
// 创建一个简单的测试组件
|
||||
// Create a simple test component
|
||||
const TestComponent = () => {
|
||||
const [src, setSrc] = React.useState('https://example.com/image.jpg');
|
||||
|
||||
@@ -235,16 +235,16 @@ describe('useImagePreview 基本功能测试', () => {
|
||||
|
||||
render(<TestComponent />);
|
||||
|
||||
// 点击确认按钮
|
||||
// Click the confirm button.
|
||||
const okButton = screen.getByTestId('modal-ok');
|
||||
fireEvent.click(okButton);
|
||||
|
||||
// 验证onChange被调用
|
||||
// Verify that onChange is invoked
|
||||
expect(onChange).toHaveBeenCalledWith('https://example.com/image.jpg', '');
|
||||
});
|
||||
|
||||
test('测试editable属性', () => {
|
||||
// 创建一个简单的测试组件
|
||||
// Create a simple test component
|
||||
const TestComponent = () => {
|
||||
const [src, setSrc] = React.useState('https://example.com/image.jpg');
|
||||
const onChange = vi.fn();
|
||||
@@ -261,7 +261,7 @@ describe('useImagePreview 基本功能测试', () => {
|
||||
|
||||
render(<TestComponent />);
|
||||
|
||||
// 验证输入框被禁用
|
||||
// Verify text box is disabled
|
||||
const urlInput = screen.getByTestId('image-url-input');
|
||||
expect(urlInput).toBeDisabled();
|
||||
});
|
||||
|
||||
@@ -23,7 +23,7 @@ import {
|
||||
isValidSize,
|
||||
} from '../../../src/components/renders/image-render/utils';
|
||||
|
||||
// 模拟 CustomError
|
||||
// Simulate CustomError
|
||||
vi.mock('@coze-arch/bot-error', () => ({
|
||||
CustomError: class CustomError extends Error {
|
||||
constructor(event: string, message: string) {
|
||||
@@ -48,7 +48,7 @@ describe('getFileExtension', () => {
|
||||
|
||||
describe('isValidSize', () => {
|
||||
test('文件大小小于限制时应返回true', () => {
|
||||
// 20MB限制
|
||||
// 20MB limit
|
||||
const validSize = 10 * 1024 * 1024; // 10MB
|
||||
expect(isValidSize(validSize)).toBe(true);
|
||||
});
|
||||
@@ -66,10 +66,10 @@ describe('isValidSize', () => {
|
||||
|
||||
describe('getBase64', () => {
|
||||
test('应该正确转换文件为base64字符串', async () => {
|
||||
// 创建一个模拟的Blob对象
|
||||
// Create a simulated blob object
|
||||
const mockBlob = new Blob(['test content'], { type: 'text/plain' });
|
||||
|
||||
// 模拟FileReader
|
||||
// Analog FileReader
|
||||
const mockFileReader = {
|
||||
readAsDataURL: vi.fn(),
|
||||
onload: null as any,
|
||||
@@ -77,36 +77,36 @@ describe('getBase64', () => {
|
||||
onabort: null as any,
|
||||
};
|
||||
|
||||
// 保存原始的FileReader
|
||||
// Save the original FileReader
|
||||
const originalFileReader = global.FileReader;
|
||||
|
||||
// 模拟FileReader构造函数
|
||||
// Mock FileReader constructor
|
||||
global.FileReader = vi.fn(() => mockFileReader) as any;
|
||||
|
||||
// 调用getBase64
|
||||
// Call getBase64
|
||||
const promise = getBase64(mockBlob);
|
||||
|
||||
// 触发onload事件
|
||||
// Trigger onload event
|
||||
mockFileReader.onload({
|
||||
target: {
|
||||
result: 'data:text/plain;base64,dGVzdCBjb250ZW50',
|
||||
},
|
||||
} as any);
|
||||
|
||||
// 验证结果
|
||||
// validation result
|
||||
const result = await promise;
|
||||
expect(result).toBe('dGVzdCBjb250ZW50');
|
||||
expect(mockFileReader.readAsDataURL).toHaveBeenCalledWith(mockBlob);
|
||||
|
||||
// 恢复原始的FileReader
|
||||
// Restore the original FileReader
|
||||
global.FileReader = originalFileReader;
|
||||
});
|
||||
|
||||
test('当FileReader.onload返回非字符串结果时应拒绝Promise', async () => {
|
||||
// 创建一个模拟的Blob对象
|
||||
// Create a simulated blob object
|
||||
const mockBlob = new Blob(['test content'], { type: 'text/plain' });
|
||||
|
||||
// 模拟FileReader
|
||||
// Analog FileReader
|
||||
const mockFileReader = {
|
||||
readAsDataURL: vi.fn(),
|
||||
onload: null as any,
|
||||
@@ -114,34 +114,34 @@ describe('getBase64', () => {
|
||||
onabort: null as any,
|
||||
};
|
||||
|
||||
// 保存原始的FileReader
|
||||
// Save the original FileReader
|
||||
const originalFileReader = global.FileReader;
|
||||
|
||||
// 模拟FileReader构造函数
|
||||
// Mock FileReader constructor
|
||||
global.FileReader = vi.fn(() => mockFileReader) as any;
|
||||
|
||||
// 调用getBase64
|
||||
// Call getBase64
|
||||
const promise = getBase64(mockBlob);
|
||||
|
||||
// 触发onload事件,但返回非字符串结果
|
||||
// Fires the onload event, but returns a non-string result
|
||||
mockFileReader.onload({
|
||||
target: {
|
||||
result: null,
|
||||
},
|
||||
} as any);
|
||||
|
||||
// 验证Promise被拒绝
|
||||
// Verification Promise Rejected
|
||||
await expect(promise).rejects.toThrow('file read invalid');
|
||||
|
||||
// 恢复原始的FileReader
|
||||
// Restore the original FileReader
|
||||
global.FileReader = originalFileReader;
|
||||
});
|
||||
|
||||
test('当FileReader.onerror触发时应拒绝Promise', async () => {
|
||||
// 创建一个模拟的Blob对象
|
||||
// Create a simulated blob object
|
||||
const mockBlob = new Blob(['test content'], { type: 'text/plain' });
|
||||
|
||||
// 模拟FileReader
|
||||
// Analog FileReader
|
||||
const mockFileReader = {
|
||||
readAsDataURL: vi.fn(),
|
||||
onload: null as any,
|
||||
@@ -149,30 +149,30 @@ describe('getBase64', () => {
|
||||
onabort: null as any,
|
||||
};
|
||||
|
||||
// 保存原始的FileReader
|
||||
// Save the original FileReader
|
||||
const originalFileReader = global.FileReader;
|
||||
|
||||
// 模拟FileReader构造函数
|
||||
// Mock FileReader constructor
|
||||
global.FileReader = vi.fn(() => mockFileReader) as any;
|
||||
|
||||
// 调用getBase64
|
||||
// Call getBase64
|
||||
const promise = getBase64(mockBlob);
|
||||
|
||||
// 触发onerror事件
|
||||
// Trigger the onerror event
|
||||
mockFileReader.onerror();
|
||||
|
||||
// 验证Promise被拒绝
|
||||
// Verification Promise Rejected
|
||||
await expect(promise).rejects.toThrow('file read fail');
|
||||
|
||||
// 恢复原始的FileReader
|
||||
// Restore the original FileReader
|
||||
global.FileReader = originalFileReader;
|
||||
});
|
||||
|
||||
test('当FileReader.onabort触发时应拒绝Promise', async () => {
|
||||
// 创建一个模拟的Blob对象
|
||||
// Create a simulated blob object
|
||||
const mockBlob = new Blob(['test content'], { type: 'text/plain' });
|
||||
|
||||
// 模拟FileReader
|
||||
// Analog FileReader
|
||||
const mockFileReader = {
|
||||
readAsDataURL: vi.fn(),
|
||||
onload: null as any,
|
||||
@@ -180,100 +180,100 @@ describe('getBase64', () => {
|
||||
onabort: null as any,
|
||||
};
|
||||
|
||||
// 保存原始的FileReader
|
||||
// Save the original FileReader
|
||||
const originalFileReader = global.FileReader;
|
||||
|
||||
// 模拟FileReader构造函数
|
||||
// Mock FileReader constructor
|
||||
global.FileReader = vi.fn(() => mockFileReader) as any;
|
||||
|
||||
// 调用getBase64
|
||||
// Call getBase64
|
||||
const promise = getBase64(mockBlob);
|
||||
|
||||
// 触发onabort事件
|
||||
// Trigger onabort event
|
||||
mockFileReader.onabort();
|
||||
|
||||
// 验证Promise被拒绝
|
||||
// Verification Promise Rejected
|
||||
await expect(promise).rejects.toThrow('file read abort');
|
||||
|
||||
// 恢复原始的FileReader
|
||||
// Restore the original FileReader
|
||||
global.FileReader = originalFileReader;
|
||||
});
|
||||
});
|
||||
|
||||
describe('getUint8Array', () => {
|
||||
test('应该正确转换文件为Uint8Array', async () => {
|
||||
// 创建一个模拟的Blob对象
|
||||
// Create a simulated blob object
|
||||
const mockBlob = new Blob(['test content'], { type: 'text/plain' });
|
||||
|
||||
// 创建一个模拟的ArrayBuffer
|
||||
const mockArrayBuffer = new ArrayBuffer(12); // 'test content' 的长度
|
||||
// Create a simulated ArrayBuffer
|
||||
const mockArrayBuffer = new ArrayBuffer(12); // Length of'test content '
|
||||
const uint8Array = new Uint8Array(mockArrayBuffer);
|
||||
for (let i = 0; i < 12; i++) {
|
||||
uint8Array[i] = 'test content'.charCodeAt(i);
|
||||
}
|
||||
|
||||
// 模拟FileReader
|
||||
// Analog FileReader
|
||||
const mockFileReader = {
|
||||
readAsArrayBuffer: vi.fn(),
|
||||
onload: null as any,
|
||||
};
|
||||
|
||||
// 保存原始的FileReader
|
||||
// Save the original FileReader
|
||||
const originalFileReader = global.FileReader;
|
||||
|
||||
// 模拟FileReader构造函数
|
||||
// Mock FileReader constructor
|
||||
global.FileReader = vi.fn(() => mockFileReader) as any;
|
||||
|
||||
// 调用getUint8Array
|
||||
// Call getUint8Array
|
||||
const promise = getUint8Array(mockBlob);
|
||||
|
||||
// 触发onload事件
|
||||
// Trigger onload event
|
||||
mockFileReader.onload({
|
||||
target: {
|
||||
result: mockArrayBuffer,
|
||||
},
|
||||
} as any);
|
||||
|
||||
// 验证结果
|
||||
// validation result
|
||||
const result = await promise;
|
||||
expect(result).toBeInstanceOf(Uint8Array);
|
||||
expect(result.length).toBe(12);
|
||||
expect(mockFileReader.readAsArrayBuffer).toHaveBeenCalledWith(mockBlob);
|
||||
|
||||
// 恢复原始的FileReader
|
||||
// Restore the original FileReader
|
||||
global.FileReader = originalFileReader;
|
||||
});
|
||||
|
||||
test('当FileReader.onload返回无效结果时应拒绝Promise', async () => {
|
||||
// 创建一个模拟的Blob对象
|
||||
// Create a simulated blob object
|
||||
const mockBlob = new Blob(['test content'], { type: 'text/plain' });
|
||||
|
||||
// 模拟FileReader
|
||||
// Analog FileReader
|
||||
const mockFileReader = {
|
||||
readAsArrayBuffer: vi.fn(),
|
||||
onload: null as any,
|
||||
};
|
||||
|
||||
// 保存原始的FileReader
|
||||
// Save the original FileReader
|
||||
const originalFileReader = global.FileReader;
|
||||
|
||||
// 模拟FileReader构造函数
|
||||
// Mock FileReader constructor
|
||||
global.FileReader = vi.fn(() => mockFileReader) as any;
|
||||
|
||||
// 调用getUint8Array
|
||||
// Call getUint8Array
|
||||
const promise = getUint8Array(mockBlob);
|
||||
|
||||
// 触发onload事件,但返回无效结果
|
||||
// The onload event is fired, but an invalid result is returned
|
||||
mockFileReader.onload({
|
||||
target: {
|
||||
result: null,
|
||||
},
|
||||
} as any);
|
||||
|
||||
// 验证Promise被拒绝
|
||||
// Verification Promise Rejected
|
||||
await expect(promise).rejects.toThrow('file read invalid');
|
||||
|
||||
// 恢复原始的FileReader
|
||||
// Restore the original FileReader
|
||||
global.FileReader = originalFileReader;
|
||||
});
|
||||
});
|
||||
|
||||
@@ -22,7 +22,7 @@ import { render, screen, fireEvent } from '@testing-library/react';
|
||||
import '@testing-library/jest-dom';
|
||||
import { ActionsRender } from '../../../src/components/renders/actions-render';
|
||||
|
||||
// 使用vi.mock的回调函数形式来避免linter错误
|
||||
// Use the callback function form of vi.mock to avoid linter errors
|
||||
vi.mock('@coze-arch/coze-design/icons', () => ({
|
||||
IconCozEdit: () => <div data-testid="edit-icon" />,
|
||||
IconCozTrashCan: () => <div data-testid="delete-icon" />,
|
||||
@@ -49,9 +49,9 @@ describe('ActionsRender', () => {
|
||||
|
||||
render(<ActionsRender record={mockRecord} index={mockIndex} />);
|
||||
|
||||
// 验证按钮被渲染
|
||||
// Verify button is rendered
|
||||
const buttons = screen.getAllByTestId('button');
|
||||
expect(buttons).toHaveLength(2); // 编辑和删除按钮
|
||||
expect(buttons).toHaveLength(2); // Edit and delete buttons
|
||||
});
|
||||
|
||||
test('应该在点击编辑按钮时调用onEdit回调', () => {
|
||||
@@ -67,11 +67,11 @@ describe('ActionsRender', () => {
|
||||
/>,
|
||||
);
|
||||
|
||||
// 点击编辑按钮
|
||||
// Click the Edit button
|
||||
const buttons = screen.getAllByTestId('button');
|
||||
fireEvent.click(buttons[0]); // 第一个按钮是编辑按钮
|
||||
fireEvent.click(buttons[0]); // The first button is the edit button
|
||||
|
||||
// 验证编辑回调被调用
|
||||
// Verify edit callback is invoked
|
||||
expect(mockOnEdit).toHaveBeenCalledWith(mockRecord, mockIndex);
|
||||
});
|
||||
|
||||
@@ -88,11 +88,11 @@ describe('ActionsRender', () => {
|
||||
/>,
|
||||
);
|
||||
|
||||
// 点击删除按钮
|
||||
// Click the Delete button.
|
||||
const buttons = screen.getAllByTestId('button');
|
||||
fireEvent.click(buttons[1]); // 第二个按钮是删除按钮
|
||||
fireEvent.click(buttons[1]); // The second button is the delete button.
|
||||
|
||||
// 验证删除回调被调用
|
||||
// Verify that the delete callback is invoked
|
||||
expect(mockOnDelete).toHaveBeenCalledWith(mockIndex);
|
||||
});
|
||||
|
||||
@@ -108,7 +108,7 @@ describe('ActionsRender', () => {
|
||||
/>,
|
||||
);
|
||||
|
||||
// 验证只有一个按钮(删除按钮)
|
||||
// Verify that there is only one button (delete button)
|
||||
const buttons = screen.getAllByTestId('button');
|
||||
expect(buttons).toHaveLength(1);
|
||||
});
|
||||
@@ -125,7 +125,7 @@ describe('ActionsRender', () => {
|
||||
/>,
|
||||
);
|
||||
|
||||
// 验证只有一个按钮(编辑按钮)
|
||||
// Verify that there is only one button (edit button)
|
||||
const buttons = screen.getAllByTestId('button');
|
||||
expect(buttons).toHaveLength(1);
|
||||
});
|
||||
|
||||
@@ -22,7 +22,7 @@ import { render, screen, fireEvent } from '@testing-library/react';
|
||||
import '@testing-library/jest-dom';
|
||||
import { EditHeaderRender } from '../../../src/components/renders/edit-header-render';
|
||||
|
||||
// 模拟依赖
|
||||
// simulated dependency
|
||||
vi.mock('@coze-arch/bot-semi', () => {
|
||||
const uiButton = ({ children, onClick, ...props }: any) => (
|
||||
<button data-testid="button" onClick={onClick} {...props}>
|
||||
@@ -82,7 +82,7 @@ describe('EditHeaderRender', () => {
|
||||
<EditHeaderRender value="测试标题" onBlur={mockOnBlur} validator={{}} />,
|
||||
);
|
||||
|
||||
// 验证预览模式显示正确的值
|
||||
// Verify that the preview mode displays the correct value
|
||||
const previewElement = screen.getByText('测试标题');
|
||||
expect(previewElement).toBeInTheDocument();
|
||||
});
|
||||
@@ -94,11 +94,11 @@ describe('EditHeaderRender', () => {
|
||||
<EditHeaderRender value="测试标题" onBlur={mockOnBlur} validator={{}} />,
|
||||
);
|
||||
|
||||
// 点击预览文本
|
||||
// Click to preview text
|
||||
const previewElement = screen.getByText('测试标题');
|
||||
fireEvent.click(previewElement);
|
||||
|
||||
// 验证输入框出现
|
||||
// Verify text box appears
|
||||
const inputElement = screen.getByTestId('input');
|
||||
expect(inputElement).toBeInTheDocument();
|
||||
expect(inputElement).toHaveValue('测试标题');
|
||||
@@ -108,7 +108,7 @@ describe('EditHeaderRender', () => {
|
||||
const mockOnBlur = vi.fn();
|
||||
const mockEditPropsOnBlur = vi.fn();
|
||||
|
||||
// 渲染组件
|
||||
// rendering component
|
||||
render(
|
||||
<EditHeaderRender
|
||||
value="测试标题"
|
||||
@@ -120,17 +120,17 @@ describe('EditHeaderRender', () => {
|
||||
/>,
|
||||
);
|
||||
|
||||
// 点击预览文本进入编辑模式
|
||||
// Click on the preview text to enter edit mode
|
||||
const previewElement = screen.getByText('测试标题');
|
||||
fireEvent.click(previewElement);
|
||||
|
||||
// 获取输入框
|
||||
// Get text box
|
||||
const inputElement = screen.getByTestId('input');
|
||||
|
||||
// 触发 blur 事件,让组件内部的 onBlurFn 函数被调用
|
||||
// The blur event is triggered, causing the onBlurFn function inside the component to be called
|
||||
fireEvent.blur(inputElement);
|
||||
|
||||
// 验证 editProps.onBlur 被调用,并且传递了正确的参数
|
||||
// Verify that editProps.onBlur is called and the correct parameters are passed
|
||||
expect(mockEditPropsOnBlur).toHaveBeenCalledWith('测试标题');
|
||||
});
|
||||
|
||||
@@ -149,15 +149,15 @@ describe('EditHeaderRender', () => {
|
||||
/>,
|
||||
);
|
||||
|
||||
// 点击预览文本进入编辑模式
|
||||
// Click on the preview text to enter edit mode
|
||||
const previewElement = screen.getByText('测试标题');
|
||||
fireEvent.click(previewElement);
|
||||
|
||||
// 获取输入框并修改值
|
||||
// Get the text box and modify the value
|
||||
const inputElement = screen.getByTestId('input');
|
||||
fireEvent.change(inputElement, { target: { value: '新标题' } });
|
||||
|
||||
// 验证 onChange 回调被调用
|
||||
// Verify that the onChange callback is invoked
|
||||
expect(mockOnChange).toHaveBeenCalledWith('新标题');
|
||||
});
|
||||
|
||||
@@ -177,11 +177,11 @@ describe('EditHeaderRender', () => {
|
||||
/>,
|
||||
);
|
||||
|
||||
// 点击删除按钮
|
||||
// Click the Delete button.
|
||||
const deleteButton = screen.getByTestId('button');
|
||||
fireEvent.click(deleteButton);
|
||||
|
||||
// 验证 onDelete 回调被调用
|
||||
// Verify that the onDelete callback is invoked
|
||||
expect(mockOnDelete).toHaveBeenCalledWith('测试标题');
|
||||
});
|
||||
|
||||
@@ -201,11 +201,11 @@ describe('EditHeaderRender', () => {
|
||||
/>,
|
||||
);
|
||||
|
||||
// 验证删除按钮被禁用
|
||||
// Verify that the delete button is disabled
|
||||
const deleteButton = screen.getByTestId('button');
|
||||
expect(deleteButton).toHaveAttribute('disabled');
|
||||
|
||||
// 点击删除按钮不应调用回调
|
||||
// Clicking the delete button should not invoke a callback
|
||||
fireEvent.click(deleteButton);
|
||||
expect(mockOnDelete).not.toHaveBeenCalled();
|
||||
});
|
||||
@@ -222,7 +222,7 @@ describe('EditHeaderRender', () => {
|
||||
/>,
|
||||
);
|
||||
|
||||
// 验证删除按钮不存在
|
||||
// Verify that the delete button does not exist
|
||||
expect(screen.queryByTestId('button')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
@@ -241,12 +241,12 @@ describe('EditHeaderRender', () => {
|
||||
/>,
|
||||
);
|
||||
|
||||
// 点击预览文本进入编辑模式
|
||||
// Click on the preview text to enter edit mode
|
||||
const previewElement = screen.getByText('测试标题');
|
||||
fireEvent.click(previewElement);
|
||||
|
||||
// 由于我们的模拟实现中,错误图标和提示是通过 suffix 属性传递的
|
||||
// 所以我们需要检查 tooltip 和 error-icon 是否存在于文档中
|
||||
// Since in our simulation implementation, error icons and hints are passed through the suffix attribute
|
||||
// So we need to check if tooltip and error-icon exist in the document
|
||||
expect(screen.getByTestId('error-icon')).toBeInTheDocument();
|
||||
expect(screen.getByTestId('tooltip')).toHaveAttribute(
|
||||
'data-content',
|
||||
|
||||
@@ -39,7 +39,7 @@ describe('TagRender', () => {
|
||||
<TagRender value="标签文本" record={mockRecord} index={mockIndex} />,
|
||||
);
|
||||
|
||||
// 验证标签内容被正确渲染
|
||||
// Verify that the tag content is rendered correctly
|
||||
const tag = screen.getByTestId('tag');
|
||||
expect(tag).toBeInTheDocument();
|
||||
expect(tag).toHaveTextContent('标签文本');
|
||||
@@ -53,7 +53,7 @@ describe('TagRender', () => {
|
||||
<TagRender value="标签文本" record={mockRecord} index={mockIndex} />,
|
||||
);
|
||||
|
||||
// 验证标签使用默认颜色
|
||||
// Verify that the label uses the default color
|
||||
const tag = screen.getByTestId('tag');
|
||||
expect(tag).toHaveAttribute('data-color', 'primary');
|
||||
});
|
||||
@@ -71,7 +71,7 @@ describe('TagRender', () => {
|
||||
/>,
|
||||
);
|
||||
|
||||
// 验证标签使用自定义颜色
|
||||
// Verify labels with custom colors
|
||||
const tag = screen.getByTestId('tag');
|
||||
expect(tag).toHaveAttribute('data-color', 'red');
|
||||
});
|
||||
@@ -84,7 +84,7 @@ describe('TagRender', () => {
|
||||
<TagRender value={undefined} record={mockRecord} index={mockIndex} />,
|
||||
);
|
||||
|
||||
// 验证标签内容为空字符串
|
||||
// Verify tag content is empty string
|
||||
const tag = screen.getByTestId('tag');
|
||||
expect(tag).toHaveTextContent('');
|
||||
});
|
||||
|
||||
@@ -22,7 +22,7 @@ import '@testing-library/jest-dom';
|
||||
|
||||
import { TextRender } from '../../../src/components/renders/text-render';
|
||||
|
||||
// 模拟依赖
|
||||
// simulated dependency
|
||||
vi.mock('@coze-arch/coze-design', () => ({
|
||||
TextArea: ({
|
||||
value,
|
||||
@@ -80,10 +80,10 @@ describe('TextRender', () => {
|
||||
/>,
|
||||
);
|
||||
|
||||
// 验证文本内容被正确渲染
|
||||
// Verify that the text content is rendered correctly
|
||||
expect(screen.getByText('测试文本')).toBeInTheDocument();
|
||||
|
||||
// 验证 TextArea 不可见
|
||||
// Verify that the TextArea is not visible
|
||||
expect(screen.queryByTestId('text-area')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
@@ -99,13 +99,13 @@ describe('TextRender', () => {
|
||||
/>,
|
||||
);
|
||||
|
||||
// 验证文本内容被正确渲染
|
||||
// Verify that the text content is rendered correctly
|
||||
expect(screen.getByText('测试文本')).toBeInTheDocument();
|
||||
|
||||
// 点击文本进入编辑模式
|
||||
// Click on the text to enter edit mode
|
||||
fireEvent.click(screen.getByText('测试文本'));
|
||||
|
||||
// 验证 TextArea 可见
|
||||
// Verify that the TextArea is visible
|
||||
expect(screen.getByTestId('text-area')).toBeInTheDocument();
|
||||
expect(screen.getByTestId('text-area')).toHaveValue('测试文本');
|
||||
});
|
||||
@@ -122,20 +122,20 @@ describe('TextRender', () => {
|
||||
/>,
|
||||
);
|
||||
|
||||
// 点击文本进入编辑模式
|
||||
// Click on the text to enter edit mode
|
||||
fireEvent.click(screen.getByText('测试文本'));
|
||||
|
||||
// 修改输入值
|
||||
// Modify input value
|
||||
fireEvent.change(screen.getByTestId('text-area'), {
|
||||
target: { value: '新文本' },
|
||||
});
|
||||
|
||||
// 验证 onChange 被调用
|
||||
// Verify that onChange is invoked
|
||||
expect(mockOnChange).toHaveBeenCalledWith('新文本', mockRecord, mockIndex);
|
||||
});
|
||||
|
||||
test('应该在失去焦点时调用 onBlur', async () => {
|
||||
// 使用 dataIndex 属性
|
||||
// Using the dataIndex property
|
||||
render(
|
||||
<TextRender
|
||||
value="测试文本"
|
||||
@@ -144,33 +144,33 @@ describe('TextRender', () => {
|
||||
onBlur={mockOnBlur}
|
||||
onChange={mockOnChange}
|
||||
editable={true}
|
||||
dataIndex="name" // 添加 dataIndex 属性
|
||||
dataIndex="name" // Add dataIndex property
|
||||
/>,
|
||||
);
|
||||
|
||||
// 点击文本进入编辑模式
|
||||
// Click on the text to enter edit mode
|
||||
fireEvent.click(screen.getByText('测试文本'));
|
||||
|
||||
// 修改输入值
|
||||
// Modify input value
|
||||
fireEvent.change(screen.getByTestId('text-area'), {
|
||||
target: { value: '新文本' },
|
||||
});
|
||||
|
||||
// 失去焦点
|
||||
// Lost focus
|
||||
fireEvent.blur(screen.getByTestId('text-area'));
|
||||
|
||||
// 验证 onBlur 被调用,并且传递了正确的参数
|
||||
// 根据组件实现,onBlur 会被调用,参数是 inputValue, updateRecord, index
|
||||
// 其中 updateRecord 是 { ...record, [dataIndex]: inputValue } 并且删除了 tableViewKey
|
||||
// Verify that onBlur is called and the correct parameters are passed
|
||||
// Depending on the component implementation, onBlur will be called with the parameters inputValue, updateRecord, index
|
||||
// Where updateRecord is {... record, [dataIndex]: inputValue} and removed tableViewKey
|
||||
await waitFor(() => {
|
||||
expect(mockOnBlur).toHaveBeenCalledWith(
|
||||
'新文本',
|
||||
{ id: '1', name: '新文本' }, // 更新后的 record
|
||||
{ id: '1', name: '新文本' }, // Updated records
|
||||
mockIndex,
|
||||
);
|
||||
});
|
||||
|
||||
// 验证组件回到只读模式
|
||||
// Verify that the component returns to read-only mode
|
||||
await waitFor(() => {
|
||||
expect(screen.queryByTestId('text-area')).not.toBeInTheDocument();
|
||||
expect(screen.getByText('新文本')).toBeInTheDocument();
|
||||
@@ -179,7 +179,7 @@ describe('TextRender', () => {
|
||||
|
||||
test('应该在验证失败时显示错误提示', () => {
|
||||
const mockValidator = {
|
||||
validate: vi.fn().mockReturnValue(true), // 返回 true 表示验证失败
|
||||
validate: vi.fn().mockReturnValue(true), // Returning true indicates that the verification failed.
|
||||
errorMsg: '输入不合法',
|
||||
};
|
||||
|
||||
@@ -192,32 +192,32 @@ describe('TextRender', () => {
|
||||
onChange={mockOnChange}
|
||||
editable={true}
|
||||
validator={mockValidator}
|
||||
isEditing={true} // 直接进入编辑模式
|
||||
isEditing={true} // Go straight to edit mode
|
||||
/>,
|
||||
);
|
||||
|
||||
// 验证 TextArea 可见
|
||||
// Verify that the TextArea is visible
|
||||
expect(screen.getByTestId('text-area')).toBeInTheDocument();
|
||||
|
||||
// 修改输入值
|
||||
// Modify input value
|
||||
fireEvent.change(screen.getByTestId('text-area'), {
|
||||
target: { value: '新文本' },
|
||||
});
|
||||
|
||||
// 验证验证函数被调用
|
||||
// The validation function is called
|
||||
expect(mockValidator.validate).toHaveBeenCalledWith(
|
||||
'新文本',
|
||||
mockRecord,
|
||||
mockIndex,
|
||||
);
|
||||
|
||||
// 验证错误状态
|
||||
// validation error status
|
||||
expect(screen.getByTestId('text-area')).toHaveAttribute(
|
||||
'data-validate-status',
|
||||
'error',
|
||||
);
|
||||
|
||||
// 验证错误图标和提示被显示
|
||||
// Validation error icons and prompts are displayed
|
||||
expect(screen.getByTestId('error-icon')).toBeInTheDocument();
|
||||
expect(screen.getByTestId('tooltip')).toHaveAttribute(
|
||||
'data-content',
|
||||
@@ -238,7 +238,7 @@ describe('TextRender', () => {
|
||||
/>,
|
||||
);
|
||||
|
||||
// 验证 TextArea 直接可见
|
||||
// Verify that the TextArea is directly visible
|
||||
expect(screen.getByTestId('text-area')).toBeInTheDocument();
|
||||
expect(screen.getByTestId('text-area')).toHaveValue('测试文本');
|
||||
});
|
||||
@@ -256,10 +256,10 @@ describe('TextRender', () => {
|
||||
/>,
|
||||
);
|
||||
|
||||
// 验证 TextArea 直接可见
|
||||
// Verify that the TextArea is directly visible
|
||||
expect(screen.getByTestId('text-area')).toBeInTheDocument();
|
||||
|
||||
// 重新渲染组件,isEditing 为 undefined
|
||||
// Render the component again, isEditing is undefined
|
||||
rerender(
|
||||
<TextRender
|
||||
value="测试文本"
|
||||
@@ -271,7 +271,7 @@ describe('TextRender', () => {
|
||||
/>,
|
||||
);
|
||||
|
||||
// 验证组件回到只读模式
|
||||
// Verify that the component returns to read-only mode
|
||||
await waitFor(() => {
|
||||
expect(screen.queryByTestId('text-area')).not.toBeInTheDocument();
|
||||
expect(screen.getByText('测试文本')).toBeInTheDocument();
|
||||
|
||||
@@ -26,7 +26,7 @@ import {
|
||||
EditToolBar,
|
||||
} from '../../../src/components/table-view/edit-menu';
|
||||
|
||||
// 模拟依赖
|
||||
// simulated dependency
|
||||
vi.mock('@coze-arch/i18n', () => ({
|
||||
I18n: {
|
||||
t: (key: string, options?: any) => {
|
||||
@@ -82,7 +82,7 @@ vi.mock('@coze-arch/coze-design/icons', () => ({
|
||||
IconCozTrashCan: () => <div data-testid="icon-trash"></div>,
|
||||
}));
|
||||
|
||||
// 模拟样式
|
||||
// simulation style
|
||||
vi.mock('../../../src/components/table-view/index.module.less', () => ({
|
||||
default: {
|
||||
'table-edit-menu': 'table-edit-menu-class',
|
||||
@@ -207,11 +207,11 @@ describe('EditMenu 组件', () => {
|
||||
expect.any(Function),
|
||||
);
|
||||
|
||||
// 触发点击事件
|
||||
// trigger click event
|
||||
window.dispatchEvent(new Event('click'));
|
||||
expect(mockOnExit).toHaveBeenCalled();
|
||||
|
||||
// 卸载组件
|
||||
// uninstall components
|
||||
unmount();
|
||||
expect(removeEventListenerSpy).toHaveBeenCalledWith(
|
||||
'click',
|
||||
@@ -260,7 +260,7 @@ describe('EditToolBar 组件', () => {
|
||||
|
||||
expect(screen.getByTestId('button-group')).toBeInTheDocument();
|
||||
expect(screen.getByText('已选择 2 项')).toBeInTheDocument();
|
||||
expect(screen.getAllByTestId('button')).toHaveLength(3); // 编辑、删除和关闭按钮
|
||||
expect(screen.getAllByTestId('button')).toHaveLength(3); // Edit, delete, and close buttons
|
||||
});
|
||||
|
||||
test('点击编辑按钮应调用onEdit回调', () => {
|
||||
@@ -352,7 +352,7 @@ describe('EditToolBar 组件', () => {
|
||||
const toolbar = screen.getByTestId('button-group').parentElement;
|
||||
expect(toolbar).toHaveStyle('margin-left: -145px');
|
||||
|
||||
// 重新渲染,只选择一个项目
|
||||
// Re-render, select only one item
|
||||
rerender(
|
||||
<EditToolBar
|
||||
configs={[]}
|
||||
|
||||
@@ -22,7 +22,7 @@ import '@testing-library/jest-dom';
|
||||
|
||||
import { TableView } from '../../../src/components/table-view';
|
||||
|
||||
// 模拟依赖
|
||||
// simulated dependency
|
||||
vi.mock('ahooks', () => ({
|
||||
useDebounceFn: fn => ({
|
||||
run: fn,
|
||||
@@ -125,7 +125,7 @@ vi.mock('../../../src/components/table-view/edit-menu', () => ({
|
||||
) : null,
|
||||
}));
|
||||
|
||||
// 模拟样式
|
||||
// simulation style
|
||||
vi.mock('../../../src/components/table-view/index.module.less', () => ({
|
||||
default: {
|
||||
'data-table-view': 'data-table-view-class',
|
||||
@@ -196,7 +196,7 @@ describe('TableView 组件', () => {
|
||||
test('当启用虚拟滚动时应渲染AutoSizer', () => {
|
||||
render(<TableView {...defaultProps} isVirtualized={true} />);
|
||||
|
||||
// 由于我们模拟了AutoSizer,我们可以检查UITable是否接收了正确的props
|
||||
// Since we simulate AutoSizer, we can check if UITable receives the correct props.
|
||||
const uiTable = screen.getByTestId('ui-table');
|
||||
expect(uiTable).toBeInTheDocument();
|
||||
});
|
||||
@@ -204,23 +204,23 @@ describe('TableView 组件', () => {
|
||||
test('当启用行选择时应传递rowSelection属性', () => {
|
||||
render(<TableView {...defaultProps} rowSelect={true} />);
|
||||
|
||||
// 由于我们模拟了UITable,我们无法直接检查rowSelection属性
|
||||
// 但我们可以检查表格是否正确渲染
|
||||
// Since we simulate UITable, we cannot directly check the rowSelection property
|
||||
// But we can check if the table is rendered correctly.
|
||||
expect(screen.getByTestId('ui-table')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('当启用列伸缩时应传递resizable属性', () => {
|
||||
render(<TableView {...defaultProps} resizable={true} />);
|
||||
|
||||
// 由于我们模拟了UITable,我们无法直接检查resizable属性
|
||||
// 但我们可以检查表格是否正确渲染
|
||||
// Since we simulate UITable, we cannot directly check the resizable property
|
||||
// But we can check if the table is rendered correctly.
|
||||
expect(screen.getByTestId('ui-table')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('当滚动到底部时应调用scrollToBottom回调', () => {
|
||||
render(<TableView {...defaultProps} isVirtualized={true} />);
|
||||
|
||||
// 模拟滚动事件
|
||||
// simulated rolling event
|
||||
act(() => {
|
||||
const onScrollProp = vi.fn();
|
||||
onScrollProp({
|
||||
@@ -231,25 +231,25 @@ describe('TableView 组件', () => {
|
||||
});
|
||||
});
|
||||
|
||||
// 由于我们模拟了useDebounceFn,scrollToBottom会被立即调用
|
||||
// 但由于我们无法直接触发onScroll回调,这个测试实际上并不能验证scrollToBottom是否被调用
|
||||
// 这里只是为了测试代码覆盖率
|
||||
// Since we emulated useDebounceFn, scrollToBottom will be called immediately
|
||||
// But since we can't directly trigger the onScroll callback, this test doesn't actually verify that scrollToBottom was called
|
||||
// This is just to test code coverage
|
||||
});
|
||||
|
||||
test('应该正确处理右键菜单', () => {
|
||||
render(<TableView {...defaultProps} rowOperation={true} />);
|
||||
|
||||
// 模拟右键点击
|
||||
// Simulated right click
|
||||
const firstRow = screen.getByTestId('row-0');
|
||||
const firstCell = firstRow.querySelector('td');
|
||||
|
||||
if (firstCell) {
|
||||
// 模拟右键点击
|
||||
// Simulated right click
|
||||
fireEvent.contextMenu(firstCell);
|
||||
|
||||
// 检查菜单是否显示
|
||||
// 注意:由于我们无法直接触发onCell.onMouseDown,这个测试实际上并不能验证菜单是否显示
|
||||
// 这里只是为了测试代码覆盖率
|
||||
// Check if the menu is displayed
|
||||
// Note: Since we cannot directly trigger onCell.onMouseDown, this test does not actually verify that the menu is displayed
|
||||
// This is just to test code coverage
|
||||
}
|
||||
});
|
||||
|
||||
@@ -258,14 +258,14 @@ describe('TableView 组件', () => {
|
||||
<TableView {...defaultProps} rowSelect={true} />,
|
||||
);
|
||||
|
||||
// 初始状态下工具栏不应显示
|
||||
// The toolbar should not be displayed in the initial state
|
||||
expect(screen.queryByTestId('edit-toolbar')).not.toBeInTheDocument();
|
||||
|
||||
// 模拟选择行
|
||||
// 注意:由于我们无法直接设置selected状态,这个测试实际上并不能验证工具栏是否显示
|
||||
// 这里只是为了测试代码覆盖率
|
||||
// Simulate select row
|
||||
// Note: Since we can't set the selected state directly, this test doesn't actually verify that the toolbar is displayed
|
||||
// This is just to test code coverage
|
||||
|
||||
// 重新渲染组件
|
||||
// Rerender component
|
||||
rerender(<TableView {...defaultProps} rowSelect={true} />);
|
||||
});
|
||||
|
||||
@@ -273,11 +273,11 @@ describe('TableView 组件', () => {
|
||||
const ref = React.createRef();
|
||||
render(<TableView {...defaultProps} ref={ref} />);
|
||||
|
||||
// 检查ref是否包含正确的方法
|
||||
// Check if the ref contains the correct method
|
||||
expect(ref.current).toHaveProperty('resetSelected');
|
||||
expect(ref.current).toHaveProperty('getTableHeight');
|
||||
|
||||
// 调用ref方法
|
||||
// Call the ref method
|
||||
act(() => {
|
||||
ref.current.resetSelected();
|
||||
});
|
||||
@@ -287,8 +287,8 @@ describe('TableView 组件', () => {
|
||||
height = ref.current.getTableHeight();
|
||||
});
|
||||
|
||||
// 验证getTableHeight返回正确的高度
|
||||
// 行高56 * 3行 + 表头高41 = 209
|
||||
// Verify that getTableHeight returns the correct height
|
||||
// Line height 56 * 3 lines + header height 41 = 209
|
||||
expect(height).toBe(209);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -19,7 +19,7 @@ import { CustomError } from '@coze-arch/bot-error';
|
||||
|
||||
import { colWidthCacheService } from '../../../src/components/table-view/service';
|
||||
|
||||
// 模拟 localStorage
|
||||
// simulated localStorage
|
||||
const localStorageMock = {
|
||||
getItem: vi.fn(),
|
||||
setItem: vi.fn(),
|
||||
@@ -27,12 +27,12 @@ const localStorageMock = {
|
||||
clear: vi.fn(),
|
||||
};
|
||||
|
||||
// 模拟 window.localStorage
|
||||
// Emulate window.localStorage
|
||||
Object.defineProperty(window, 'localStorage', {
|
||||
value: localStorageMock,
|
||||
});
|
||||
|
||||
// 模拟 CustomError
|
||||
// Simulate CustomError
|
||||
vi.mock('@coze-arch/bot-error', () => {
|
||||
const mockCustomError = vi.fn().mockImplementation((event, message) => {
|
||||
const error = new Error(message);
|
||||
@@ -59,22 +59,22 @@ describe('ColWidthCacheService', () => {
|
||||
|
||||
describe('initWidthMap', () => {
|
||||
test('当 localStorage 中不存在缓存时应该初始化一个空 Map', () => {
|
||||
// 模拟 localStorage.getItem 返回 null
|
||||
// Simulate localStorage.getItem returns null
|
||||
localStorageMock.getItem.mockReturnValueOnce(null);
|
||||
|
||||
colWidthCacheService.initWidthMap();
|
||||
|
||||
// 验证 localStorage.setItem 被调用,并且参数是一个空 Map 的字符串表示
|
||||
// Verify that localStorage.setItem is called and that the argument is a string representation of an empty Map
|
||||
expect(localStorageMock.setItem).toHaveBeenCalledWith(mapName, '[]');
|
||||
});
|
||||
|
||||
test('当 localStorage 中已存在缓存时不应该重新初始化', () => {
|
||||
// 模拟 localStorage.getItem 返回一个已存在的缓存
|
||||
// Simulate localStorage.getItem to return an existing cache
|
||||
localStorageMock.getItem.mockReturnValueOnce('[["table1",{"col1":100}]]');
|
||||
|
||||
colWidthCacheService.initWidthMap();
|
||||
|
||||
// 验证 localStorage.setItem 没有被调用
|
||||
// Verify that localStorage.setItem is not called
|
||||
expect(localStorageMock.setItem).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
@@ -83,18 +83,18 @@ describe('ColWidthCacheService', () => {
|
||||
test('当 tableKey 为空时不应该设置缓存', () => {
|
||||
colWidthCacheService.setWidthMap({ col1: 100 }, undefined);
|
||||
|
||||
// 验证 localStorage.getItem 和 localStorage.setItem 都没有被调用
|
||||
// Verify that neither localStorage.getItem nor localStorage.setItem is called
|
||||
expect(localStorageMock.getItem).not.toHaveBeenCalled();
|
||||
expect(localStorageMock.setItem).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('当缓存中已存在相同 tableKey 时应该更新缓存', () => {
|
||||
// 模拟 localStorage.getItem 返回一个已存在的缓存
|
||||
// Simulate localStorage.getItem to return an existing cache
|
||||
localStorageMock.getItem.mockReturnValueOnce('[["table1",{"col1":100}]]');
|
||||
|
||||
colWidthCacheService.setWidthMap({ col1: 200 }, 'table1');
|
||||
|
||||
// 验证 localStorage.setItem 被调用,并且参数是更新后的缓存
|
||||
// Verify that localStorage.setItem is called and that the parameter is the updated cache
|
||||
expect(localStorageMock.setItem).toHaveBeenCalledWith(
|
||||
mapName,
|
||||
'[["table1",{"col1":200}]]',
|
||||
@@ -102,12 +102,12 @@ describe('ColWidthCacheService', () => {
|
||||
});
|
||||
|
||||
test('当缓存中不存在相同 tableKey 且缓存未满时应该添加新缓存', () => {
|
||||
// 模拟 localStorage.getItem 返回一个已存在的缓存
|
||||
// Simulate localStorage.getItem to return an existing cache
|
||||
localStorageMock.getItem.mockReturnValueOnce('[["table1",{"col1":100}]]');
|
||||
|
||||
colWidthCacheService.setWidthMap({ col1: 200 }, 'table2');
|
||||
|
||||
// 验证 localStorage.setItem 被调用,并且参数是添加新缓存后的结果
|
||||
// Verify that localStorage.setItem is called and that the argument is the result of adding a new cache
|
||||
expect(localStorageMock.setItem).toHaveBeenCalledWith(
|
||||
mapName,
|
||||
'[["table1",{"col1":100}],["table2",{"col1":200}]]',
|
||||
@@ -115,37 +115,37 @@ describe('ColWidthCacheService', () => {
|
||||
});
|
||||
|
||||
test('当缓存中不存在相同 tableKey 且缓存已满时应该移除最旧的缓存并添加新缓存', () => {
|
||||
// 创建一个已满的缓存(容量为 20)
|
||||
// Create a full cache (capacity 20)
|
||||
const fullCache = new Map();
|
||||
for (let i = 0; i < colWidthCacheService.capacity; i++) {
|
||||
fullCache.set(`table${i}`, { col1: 100 });
|
||||
}
|
||||
|
||||
// 模拟 localStorage.getItem 返回已满的缓存
|
||||
// Simulate localStorage.getItem returns a full cache
|
||||
localStorageMock.getItem.mockReturnValueOnce(
|
||||
JSON.stringify(Array.from(fullCache)),
|
||||
);
|
||||
|
||||
colWidthCacheService.setWidthMap({ col1: 200 }, 'tableNew');
|
||||
|
||||
// 验证 localStorage.setItem 被调用
|
||||
// Verify that localStorage.setItem is called
|
||||
expect(localStorageMock.setItem).toHaveBeenCalled();
|
||||
|
||||
// 解析设置的新缓存
|
||||
// New cache for parsing settings
|
||||
const setItemCall = localStorageMock.setItem.mock.calls[0];
|
||||
const newCacheStr = setItemCall[1];
|
||||
const newCache = JSON.parse(newCacheStr);
|
||||
|
||||
// 验证新缓存的大小仍然是容量限制
|
||||
// Verify that the size of the new cache is still the capacity limit
|
||||
expect(newCache.length).toBe(colWidthCacheService.capacity);
|
||||
|
||||
// 验证最旧的缓存(table0)被移除
|
||||
// Verify that the oldest cache (table0) is removed
|
||||
const hasOldestCache = newCache.some(
|
||||
([key]: [string, any]) => key === 'table0',
|
||||
);
|
||||
expect(hasOldestCache).toBe(false);
|
||||
|
||||
// 验证新缓存被添加
|
||||
// Verify that the new cache is added
|
||||
const hasNewCache = newCache.some(
|
||||
([key]: [string, any]) => key === 'tableNew',
|
||||
);
|
||||
@@ -153,12 +153,12 @@ describe('ColWidthCacheService', () => {
|
||||
});
|
||||
|
||||
test('当 localStorage 操作抛出异常时应该抛出 CustomError', () => {
|
||||
// 模拟 localStorage.getItem 抛出异常
|
||||
// Simulate localStorage.getItem throwing an exception
|
||||
localStorageMock.getItem.mockImplementationOnce(() => {
|
||||
throw new Error('localStorage error');
|
||||
});
|
||||
|
||||
// 验证调用 setWidthMap 会抛出 CustomError
|
||||
// Verify that calling setWidthMap throws a CustomError
|
||||
expect(() =>
|
||||
colWidthCacheService.setWidthMap({ col1: 100 }, 'table1'),
|
||||
).toThrow(CustomError);
|
||||
@@ -167,27 +167,27 @@ describe('ColWidthCacheService', () => {
|
||||
|
||||
describe('getTableWidthMap', () => {
|
||||
test('当缓存中存在 tableKey 时应该返回对应的缓存并更新其位置', () => {
|
||||
// 模拟 localStorage.getItem 返回一个已存在的缓存
|
||||
// Simulate localStorage.getItem to return an existing cache
|
||||
localStorageMock.getItem.mockReturnValueOnce(
|
||||
'[["table1",{"col1":100}],["table2",{"col1":200}]]',
|
||||
);
|
||||
|
||||
const result = colWidthCacheService.getTableWidthMap('table1');
|
||||
|
||||
// 验证返回正确的缓存
|
||||
// Verify that the correct cache is returned
|
||||
expect(result).toEqual({ col1: 100 });
|
||||
|
||||
// 注意:实际实现中并没有调用 localStorage.setItem,所以移除这个期望
|
||||
// 只验证返回的缓存数据是否正确
|
||||
// Note: The actual implementation does not call localStorage.setItem, so remove this expectation
|
||||
// Only verify that the cached data returned is correct
|
||||
});
|
||||
|
||||
test('当 localStorage 操作抛出异常时应该抛出 CustomError', () => {
|
||||
// 模拟 localStorage.getItem 抛出异常
|
||||
// Simulate localStorage.getItem throwing an exception
|
||||
localStorageMock.getItem.mockImplementationOnce(() => {
|
||||
throw new Error('localStorage error');
|
||||
});
|
||||
|
||||
// 验证调用 getTableWidthMap 会抛出 CustomError
|
||||
// Verify that calling getTableWidthMap throws a CustomError
|
||||
expect(() => colWidthCacheService.getTableWidthMap('table1')).toThrow(
|
||||
CustomError,
|
||||
);
|
||||
|
||||
@@ -127,34 +127,34 @@ describe('utils', () => {
|
||||
onDelete,
|
||||
});
|
||||
|
||||
// 验证返回的配置对象包含正确的菜单项
|
||||
// Verify that the returned configuration object contains the correct menu items
|
||||
expect(result).toHaveProperty(EditMenuItem.EDIT);
|
||||
expect(result).toHaveProperty(EditMenuItem.DELETE);
|
||||
expect(result).toHaveProperty(EditMenuItem.DELETEALL);
|
||||
|
||||
// 验证编辑菜单项
|
||||
// Verify edit menu item
|
||||
expect(result[EditMenuItem.EDIT].text).toBe('knowledge_tableview_01');
|
||||
expect(result[EditMenuItem.EDIT].icon).toBeDefined();
|
||||
|
||||
// 验证删除菜单项
|
||||
// Verify deletion of menu items
|
||||
expect(result[EditMenuItem.DELETE].text).toBe('knowledge_tableview_02');
|
||||
expect(result[EditMenuItem.DELETE].icon).toBeDefined();
|
||||
|
||||
// 验证批量删除菜单项
|
||||
// Verify bulk deletion of menu items
|
||||
expect(result[EditMenuItem.DELETEALL].text).toBe(
|
||||
'knowledge_tableview_02',
|
||||
);
|
||||
expect(result[EditMenuItem.DELETEALL].icon).toBeDefined();
|
||||
|
||||
// 测试点击编辑菜单项
|
||||
// Test click edit menu item
|
||||
result[EditMenuItem.EDIT].onClick();
|
||||
expect(onEdit).toHaveBeenCalledWith(record, indexs[0]);
|
||||
|
||||
// 测试点击删除菜单项
|
||||
// Test Click Delete Menu Item
|
||||
result[EditMenuItem.DELETE].onClick();
|
||||
expect(onDelete).toHaveBeenCalledWith(indexs);
|
||||
|
||||
// 测试点击批量删除菜单项
|
||||
// Test click to delete menu items in bulk
|
||||
result[EditMenuItem.DELETEALL].onClick();
|
||||
expect(onDelete).toHaveBeenCalledWith(indexs);
|
||||
});
|
||||
@@ -167,18 +167,18 @@ describe('utils', () => {
|
||||
selected: { record, indexs },
|
||||
});
|
||||
|
||||
// 验证返回的配置对象包含正确的菜单项
|
||||
// Verify that the returned configuration object contains the correct menu items
|
||||
expect(result).toHaveProperty(EditMenuItem.EDIT);
|
||||
expect(result).toHaveProperty(EditMenuItem.DELETE);
|
||||
expect(result).toHaveProperty(EditMenuItem.DELETEALL);
|
||||
|
||||
// 测试点击编辑菜单项不应该抛出错误
|
||||
// Tests that clicking on the edit menu item should not throw an error
|
||||
expect(() => result[EditMenuItem.EDIT].onClick()).not.toThrow();
|
||||
|
||||
// 测试点击删除菜单项不应该抛出错误
|
||||
// Test that clicking on the delete menu item should not throw an error
|
||||
expect(() => result[EditMenuItem.DELETE].onClick()).not.toThrow();
|
||||
|
||||
// 测试点击批量删除菜单项不应该抛出错误
|
||||
// Test clicking to delete menu items in bulk should not throw an error
|
||||
expect(() => result[EditMenuItem.DELETEALL].onClick()).not.toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -26,12 +26,12 @@ export interface ActionsRenderProps {
|
||||
index: number;
|
||||
editProps?: {
|
||||
disabled: boolean;
|
||||
// 编辑回调
|
||||
// edit callback
|
||||
onEdit?: (record: TableViewRecord, index: number) => void;
|
||||
};
|
||||
deleteProps?: {
|
||||
disabled: boolean;
|
||||
// 删除回调
|
||||
// Delete callback
|
||||
onDelete?: (index: number) => void;
|
||||
};
|
||||
className?: string;
|
||||
|
||||
@@ -25,20 +25,20 @@ import styles from './index.module.less';
|
||||
export interface EditHeaderRenderProps {
|
||||
value: string;
|
||||
deleteProps?: {
|
||||
// 禁用删除
|
||||
// disable deletion
|
||||
disabled: boolean;
|
||||
// 删除回调
|
||||
// Delete callback
|
||||
onDelete?: (v: string) => void;
|
||||
};
|
||||
editProps?: {
|
||||
// 编辑回调
|
||||
// edit callback
|
||||
onChange?: (v: string) => void;
|
||||
// 失焦回调
|
||||
// out of focus callback
|
||||
onBlur?: (v: string) => void;
|
||||
};
|
||||
// 失焦回调
|
||||
// out of focus callback
|
||||
onBlur: (v: string) => void;
|
||||
// 表头校验逻辑
|
||||
// header check logic
|
||||
validator: ValidatorProps;
|
||||
editable?: boolean;
|
||||
}
|
||||
@@ -75,7 +75,7 @@ export const EditHeaderRender = ({
|
||||
const isError = useMemo(() => validate && validate(value), [inputValue]);
|
||||
return (
|
||||
<div className={styles['edit-header-render']}>
|
||||
{/* 编辑态组件 */}
|
||||
{/* edit state component */}
|
||||
{isEditCom && (
|
||||
<UIInput
|
||||
autoFocus
|
||||
@@ -100,7 +100,7 @@ export const EditHeaderRender = ({
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* 预览态组件 */}
|
||||
{/* preview component */}
|
||||
{!isEditCom && (
|
||||
<div
|
||||
className={styles['header-preview']}
|
||||
@@ -110,7 +110,7 @@ export const EditHeaderRender = ({
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* 列删除按钮 */}
|
||||
{/* column delete button */}
|
||||
{editable && (
|
||||
<UIButton
|
||||
disabled={deleteDisabled}
|
||||
|
||||
@@ -23,7 +23,7 @@ import styles from '../index.module.less';
|
||||
import { useImagePreview } from './use-image-preview';
|
||||
export interface ImageRenderProps {
|
||||
srcList: string[];
|
||||
// 图片是否可编辑,默认为false
|
||||
// Whether the picture can be edited, the default is false
|
||||
editable?: boolean;
|
||||
onChange?: (tosKey: string, src: string) => void;
|
||||
dataIndex?: string;
|
||||
@@ -60,7 +60,7 @@ const ImageContainer = ({
|
||||
}}
|
||||
preview={false}
|
||||
src={src}
|
||||
// 失败时兜底图
|
||||
// bottom line on failure
|
||||
fallback={
|
||||
<IconImageFailOutlined
|
||||
className={styles['image-failed']}
|
||||
@@ -70,7 +70,7 @@ const ImageContainer = ({
|
||||
}}
|
||||
/>
|
||||
}
|
||||
// 图片加载时的占位图,主要用于大图加载
|
||||
// The placeholder map when the picture is loaded, mainly used for large image loading
|
||||
placeholder={<div className="image-skeleton" onClick={onClick} />}
|
||||
/>
|
||||
))}
|
||||
|
||||
@@ -74,7 +74,7 @@ export const useImagePreview = ({
|
||||
return;
|
||||
}
|
||||
try {
|
||||
// 业务
|
||||
// business
|
||||
const { name, fileInstance, url } = file;
|
||||
setUploading(true);
|
||||
if (fileInstance) {
|
||||
|
||||
@@ -70,7 +70,7 @@ export const TextRender = ({
|
||||
try {
|
||||
await onBlur(inputValue, updateRecord, index);
|
||||
} catch (e) {
|
||||
// 更新失败,恢复原值
|
||||
// Update failed, restore original value
|
||||
console.log('update table content error', e);
|
||||
setInputValue(String(value));
|
||||
}
|
||||
@@ -86,7 +86,7 @@ export const TextRender = ({
|
||||
}
|
||||
setInputValue(v);
|
||||
};
|
||||
// 校验状态
|
||||
// check state
|
||||
const isError = useMemo(
|
||||
() => !!validate?.(String(inputValue), record, index),
|
||||
[inputValue, validate],
|
||||
@@ -113,7 +113,7 @@ export const TextRender = ({
|
||||
className={`${styles['cell-text-render']} text-render-wrapper`}
|
||||
data-testid={CommonE2e.CommonTableViewTextRender}
|
||||
>
|
||||
{/* 编辑态组件 */}
|
||||
{/* edit state component */}
|
||||
{isEditCom ? (
|
||||
<span
|
||||
className={`${styles['cell-text-edit']} ${
|
||||
@@ -141,7 +141,7 @@ export const TextRender = ({
|
||||
</span>
|
||||
) : null}
|
||||
|
||||
{/* 预览态组件 */}
|
||||
{/* preview component */}
|
||||
{!isEditCom && (
|
||||
<div
|
||||
className={`${styles['cell-text-preview']} text-content`}
|
||||
|
||||
@@ -42,7 +42,7 @@ export interface EditMenuProps {
|
||||
};
|
||||
onExit?: () => void | Promise<void>;
|
||||
onDelete?: (indexs: (string | number)[]) => void | Promise<void>;
|
||||
// 行操作编辑行的回调
|
||||
// Line operations edit line callbacks
|
||||
onEdit?: (
|
||||
record: TableViewRecord,
|
||||
index: string | number,
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
|
||||
.table-wrapper {
|
||||
:global {
|
||||
/** 公共样式 **/
|
||||
/** Common Style **/
|
||||
|
||||
/** 重置table背景色 */
|
||||
/** Reset table background color */
|
||||
.semi-table-tbody>.semi-table-row,
|
||||
.semi-table-thead>.semi-table-row>.semi-table-row-head,
|
||||
.semi-table-tbody>.semi-table-row>.semi-table-cell-fixed-left,
|
||||
@@ -37,7 +37,7 @@
|
||||
}
|
||||
|
||||
|
||||
/** table header样式 **/
|
||||
/** Table header style **/
|
||||
.semi-table-thead {
|
||||
// 拖拽列宽度的图标样式
|
||||
&:hover {
|
||||
@@ -85,13 +85,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
/** table body部分样式 **/
|
||||
/** Table body part style **/
|
||||
.semi-table-tbody {
|
||||
.semi-table-row {
|
||||
>.semi-table-row-cell {
|
||||
/**
|
||||
* table 开启虚拟滚动后 单元格会加上 overflow: hidden
|
||||
* 未开启虚拟滚动情况下正常展示溢出内容
|
||||
* After table turns on virtual scrolling, the cell will be added with overflow: hidden.
|
||||
* Display overflow content normally without virtual scrolling enabled
|
||||
*/
|
||||
overflow: visible;
|
||||
border-top: 1px solid var(--coz-stroke-primary);
|
||||
|
||||
@@ -52,40 +52,40 @@ import { EditMenu, EditToolBar } from './edit-menu';
|
||||
import styles from './index.module.less';
|
||||
|
||||
export interface TableViewProps {
|
||||
// 唯一标识表,且会作为列宽缓存map中的key值
|
||||
// Uniquely identifies the table and is used as the key value in the column width cache map
|
||||
tableKey?: string;
|
||||
// 类名,用于样式覆盖
|
||||
// Class name for style overrides
|
||||
className?: string;
|
||||
// 编辑配置
|
||||
// Edit Configuration
|
||||
editProps?: {
|
||||
// 数据删除的回调,支持批量
|
||||
// Callback for data deletion, batch support
|
||||
onDelete?: (indexs: (string | number)[]) => void;
|
||||
// 行操作编辑行的回调
|
||||
// Line operations edit line callbacks
|
||||
onEdit?: (record: TableViewRecord, index: string | number) => void;
|
||||
};
|
||||
// 滚动到底部的回调
|
||||
// Scroll to the bottom of the callback
|
||||
scrollToBottom?: () => void | Promise<void>;
|
||||
// 拖拽钩子
|
||||
// Drag hook
|
||||
onResize?: (col: TableViewColumns) => void;
|
||||
// 是否开启虚拟滚动,默认为false
|
||||
// Whether to enable virtual scrolling, the default is false
|
||||
isVirtualized?: boolean;
|
||||
// 是否开启伸缩列,默认为false
|
||||
// Whether to enable scaled columns, the default is false
|
||||
resizable?: boolean;
|
||||
// 是否开启行选择,默认为false
|
||||
// Whether to enable line selection, the default is false
|
||||
rowSelect?: boolean;
|
||||
// 是否支持行操作,默认为false
|
||||
// Whether line operations are supported, the default is false
|
||||
rowOperation?: boolean;
|
||||
// 数据
|
||||
// data
|
||||
dataSource: TableViewRecord[];
|
||||
// 表头项
|
||||
// header item
|
||||
columns: TableViewColumns[];
|
||||
// 数据为空的兜底展示
|
||||
// The data is empty.
|
||||
empty?: ReactNode;
|
||||
// loading
|
||||
loading?: boolean;
|
||||
// 不消费,仅用于触发渲染的state,需优化
|
||||
// No consumption, only used to trigger the rendered state, which needs to be optimized
|
||||
resizeTriState?: number;
|
||||
// 额外 tableProps
|
||||
// Additional tableProps
|
||||
tableProps?: TableProps;
|
||||
}
|
||||
export interface TableViewMethods {
|
||||
@@ -204,7 +204,7 @@ export const TableView = forwardRef<TableViewMethods, TableViewProps>(
|
||||
if (e.button === MOUSE_RIGHT_BTN && rowOperation) {
|
||||
e.preventDefault();
|
||||
const { offsetWidth, offsetHeight } = document.body;
|
||||
// 如果右键位置非选中项,取消选中
|
||||
// If the right-click position is not selected, uncheck it
|
||||
if (
|
||||
rowIndex &&
|
||||
selected?.length &&
|
||||
@@ -212,7 +212,7 @@ export const TableView = forwardRef<TableViewMethods, TableViewProps>(
|
||||
) {
|
||||
setSelected([]);
|
||||
}
|
||||
// 右键展示菜单
|
||||
// right-click to display the menu
|
||||
setFocusRow(rowIndex);
|
||||
setMenuVisible(true);
|
||||
setMenuStyle({
|
||||
@@ -283,8 +283,8 @@ export const TableView = forwardRef<TableViewMethods, TableViewProps>(
|
||||
scrollDirection === 'forward' &&
|
||||
scrollOffset &&
|
||||
/**
|
||||
* 这一行一点余量都没留 可能在不同浏览器渲染下会有 bad case 导致无法满足条件
|
||||
* 如果有遇到类似反馈可以优先排查这里
|
||||
* This line has no margin at all, and there may be bad cases in different browsers that cannot meet the conditions.
|
||||
* If you encounter similar feedback, you can give priority to checking here.
|
||||
*/
|
||||
scrollOffset + height - HEADER_SIZE >= tableData.length * ITEM_SIZE &&
|
||||
!scrollUpdateWasRequested &&
|
||||
@@ -330,7 +330,7 @@ export const TableView = forwardRef<TableViewMethods, TableViewProps>(
|
||||
onResize: col =>
|
||||
onResize ? onResize(col) : resizeFn(col),
|
||||
onResizeStop: col => {
|
||||
// resize完后缓存列宽
|
||||
// Cache column width after resizing
|
||||
const resizedCols = newColumns.map(oCol => {
|
||||
if (oCol.dataIndex === col.dataIndex) {
|
||||
return col;
|
||||
|
||||
@@ -18,7 +18,7 @@ import { REPORT_EVENTS } from '@coze-arch/report-events';
|
||||
import { CustomError } from '@coze-arch/bot-error';
|
||||
|
||||
/**
|
||||
* 缓存列宽的方法类
|
||||
* Method class with cache column width
|
||||
*/
|
||||
|
||||
class ColWidthCacheService {
|
||||
@@ -46,18 +46,18 @@ class ColWidthCacheService {
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化伸缩列缓存
|
||||
* Initializing the scaled column cache
|
||||
*/
|
||||
initWidthMap() {
|
||||
const widthMap = window.localStorage.getItem(this.mapName);
|
||||
if (!widthMap) {
|
||||
// 利用Map可记录键值对顺序的特性完成一个简易的LRU
|
||||
// Completing a simple LRU using the characteristic that Map can record the order of key-value pairs
|
||||
window.localStorage.setItem(this.mapName, this.mapToString(new Map()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置列宽缓存,若超过缓存个数,删除map中最近未使用的值
|
||||
* Set the column width cache, if it exceeds the number of caches, delete the most recently unused value in the map
|
||||
*/
|
||||
setWidthMap(widthMap: Record<string, number>, tableKey?: string) {
|
||||
if (!tableKey) {
|
||||
@@ -68,11 +68,11 @@ class ColWidthCacheService {
|
||||
window.localStorage.getItem(this.mapName) || '',
|
||||
);
|
||||
if (cacheWidthMap.has(tableKey)) {
|
||||
// 存在即更新(删除后加入)
|
||||
// Exist and update (join after deletion)
|
||||
cacheWidthMap.delete(tableKey);
|
||||
} else if (cacheWidthMap.size >= this.capacity) {
|
||||
// 不存在即加入
|
||||
// 缓存超过最大值,则移除最近没有使用的
|
||||
// Join if you don't exist
|
||||
// If the cache exceeds the maximum value, remove the recently unused
|
||||
cacheWidthMap.delete(cacheWidthMap.keys().next().value);
|
||||
}
|
||||
cacheWidthMap.set(tableKey, widthMap);
|
||||
@@ -89,7 +89,7 @@ class ColWidthCacheService {
|
||||
}
|
||||
|
||||
/**
|
||||
* 以表维度查询列宽缓存信息
|
||||
* Query column width cache information in table dimension
|
||||
* @param tableKey
|
||||
*/
|
||||
getTableWidthMap(tableKey: string) {
|
||||
@@ -97,7 +97,7 @@ class ColWidthCacheService {
|
||||
const cacheWidthMap = this.stringToMap(
|
||||
window.localStorage.getItem(this.mapName) || '',
|
||||
);
|
||||
// 存在即更新
|
||||
// exist and update
|
||||
const temp = cacheWidthMap.get(tableKey);
|
||||
cacheWidthMap.delete(tableKey);
|
||||
cacheWidthMap.set(tableKey, temp);
|
||||
|
||||
@@ -39,7 +39,7 @@ export interface GetRowOpConfig {
|
||||
}
|
||||
|
||||
/**
|
||||
* 表格列伸缩时的回调,用于限制伸缩边界
|
||||
* Callbacks when table columns are scaled to limit the scaling boundaries
|
||||
* @param column
|
||||
* @returns
|
||||
*/
|
||||
@@ -64,7 +64,7 @@ export const getRowKey: RowKey<TableViewRecord> = (record?: TableViewRecord) =>
|
||||
record?.tableViewKey || '';
|
||||
|
||||
/**
|
||||
* 获取行操作配置
|
||||
* Get row operation configuration
|
||||
* @param record
|
||||
* @param indexs
|
||||
* @param onEdit
|
||||
|
||||
Reference in New Issue
Block a user