Merge branch 'main' into next

This commit is contained in:
mytharcher 2025-04-16 21:06:12 +08:00
commit 42a9d5a6cb
10 changed files with 88 additions and 7 deletions

View File

@ -821,6 +821,7 @@
"File size should not exceed {{size}}.": "文件大小不能超过 {{size}}",
"File size exceeds the limit": "文件大小超过限制",
"File type is not allowed": "文件类型不允许",
"Uploading": "上传中",
"Incomplete uploading files need to be resolved": "未完成上传的文件需要处理",
"Default title for each record": "用作数据的默认标题",
"If collection inherits, choose inherited collections as templates": "当前表有继承关系时,可选择继承链路上的表作为模板来源",

View File

@ -42,6 +42,8 @@ function InputInner(props: NocoBaseInputProps) {
return <AntdInput {...others} onChange={handleChange} />;
}
InputInner.Password = AntdInput.Password;
export const Input: ComposedInput = Object.assign(
connect(
InputInner,

View File

@ -799,7 +799,7 @@ export function useDesignable() {
return component;
}
const c = get(components, component);
return c[LAZY_COMPONENT_KEY] ?? c;
return c?.[LAZY_COMPONENT_KEY] ?? c;
},
[get],
),

View File

@ -15,3 +15,4 @@ export * from './datetime-interface';
export * from './datetime-no-tz-interface';
export * from './boolean-interface';
export * from './date-interface';
export * from './time-interface';

View File

@ -0,0 +1,26 @@
/**
* This file is part of the NocoBase (R) project.
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
* Authors: NocoBase Team.
*
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
* For more information, please refer to: https://www.nocobase.com/agreement.
*/
import dayjs from 'dayjs';
import { BaseInterface } from './base-interface';
export class TimeInterface extends BaseInterface {
toValue(value: any, ctx?: any) {
if (this.validate(value)) {
const result = dayjs.utc(value).format('HH:mm:ss');
return result;
}
return value;
}
validate(value) {
const result = dayjs(value).isValid();
return result;
}
}

View File

@ -16,6 +16,7 @@ import {
MultipleSelectInterface,
PercentInterface,
SelectInterface,
TimeInterface,
} from './index';
import { ManyToOneInterface } from './many-to-one-interface';
import { ManyToManyInterface } from './many-to-many-interface';
@ -50,6 +51,7 @@ const interfaces = {
o2m: OneToManyInterface,
m2o: ManyToOneInterface,
m2m: ManyToManyInterface,
time: TimeInterface,
};
export function registerInterfaces(db: Database) {

View File

@ -2155,4 +2155,53 @@ describe('xlsx importer', () => {
expect(await Post.repository.count()).toBe(1);
});
it('should import time field successfully', async () => {
const TimeCollection = app.db.collection({
name: 'time_tests',
fields: [
{
type: 'time',
name: 'brithtime',
},
],
});
await app.db.sync();
const templateCreator = new TemplateCreator({
collection: TimeCollection,
explain: 'test',
columns: [
{
dataIndex: ['birthtime'],
defaultTitle: '出生时间',
},
],
});
const template = (await templateCreator.run({ returnXLSXWorkbook: true })) as XLSX.WorkBook;
const worksheet = template.Sheets[template.SheetNames[0]];
XLSX.utils.sheet_add_aoa(worksheet, [['12:12:12']], {
origin: 'A3',
});
const importer = new XlsxImporter({
collectionManager: app.mainDataSource.collectionManager,
collection: TimeCollection,
explain: 'test',
columns: [
{
dataIndex: ['brithtime'],
defaultTitle: '出生时间',
},
],
workbook: template,
});
await importer.run();
const count = await TimeCollection.repository.count();
expect(count).toBe(1);
});
});

View File

@ -36,6 +36,7 @@ async function importXlsxAction(ctx: Context, next: Next) {
const workbook = XLSX.read(ctx.file.buffer, {
type: 'buffer',
sheetRows: readLimit,
cellDates: true,
});
const repository = ctx.getCurrentRepository() as Repository;

View File

@ -8,6 +8,7 @@
*/
import React, { createContext, useCallback, useContext, useEffect, useState } from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import { useField, useFieldSchema, useForm } from '@formily/react';
import { FormLayout } from '@formily/antd-v5';
import { Button, Card, ConfigProvider, Descriptions, Space, Spin, Tag } from 'antd';
@ -47,7 +48,6 @@ import WorkflowPlugin, {
useAvailableUpstreams,
useFlowContext,
EXECUTION_STATUS,
JOB_STATUS,
WorkflowTitle,
TASK_STATUS,
usePopupRecordContext,
@ -56,8 +56,7 @@ import WorkflowPlugin, {
import { NAMESPACE, useLang } from '../locale';
import { FormBlockProvider } from './instruction/FormBlockProvider';
import { ManualFormType, manualFormTypes } from './instruction/SchemaConfig';
import { TaskStatusOptionsMap } from '../common/constants';
import { useNavigate, useParams } from 'react-router-dom';
import { TaskStatusOptionsMap, TASK_STATUS } from '../common/constants';
function TaskStatusColumn(props) {
const recordData = useCollectionRecordData();
@ -654,11 +653,11 @@ function TaskItem() {
const StatusFilterMap = {
pending: {
status: JOB_STATUS.PENDING,
status: TASK_STATUS.PENDING,
'execution.status': EXECUTION_STATUS.STARTED,
},
completed: {
status: JOB_STATUS.RESOLVED,
status: [TASK_STATUS.RESOLVED, TASK_STATUS.REJECTED],
},
};

View File

@ -14,7 +14,7 @@ export const MANUAL_TASK_TYPE = 'manual';
export const TASK_STATUS = {
PENDING: 0,
RESOLVED: 1,
REJECTED: -1,
REJECTED: -5,
};
export const TaskStatusOptions = [