mirror of
https://gitee.com/nocobase/nocobase.git
synced 2024-11-29 18:58:26 +08:00
chore: unsupportedFields in view collection (#4155)
* chore: unsupportedFields in view collection * refactor: view display unsupportedFields * refactor: locale improve * chore: test * chore: test * fix: bug --------- Co-authored-by: katherinehhh <katherine_15995@163.com>
This commit is contained in:
parent
4165d8baae
commit
7748a33138
@ -175,6 +175,7 @@ export const EditFieldAction = (props) => {
|
||||
const compile = useCompile();
|
||||
const [data, setData] = useState<any>({});
|
||||
const { isDialect } = useDialect();
|
||||
const { template } = parentRecord || {};
|
||||
|
||||
const scopeKeyOptions = useMemo(() => {
|
||||
return (
|
||||
@ -248,7 +249,7 @@ export const EditFieldAction = (props) => {
|
||||
isDialect,
|
||||
disabledJSONB: true,
|
||||
scopeKeyOptions,
|
||||
createMainOnly: true,
|
||||
createMainOnly: template !== 'foreign',
|
||||
...scope,
|
||||
}}
|
||||
/>
|
||||
|
@ -7,6 +7,7 @@ import { ResourceActionContext, useCompile } from '../../../';
|
||||
import { useAPIClient } from '../../../api-client';
|
||||
import { useFieldInterfaceOptions } from '../../Configuration/interfaces';
|
||||
import { useCollectionManager_deprecated } from '../../hooks/useCollectionManager_deprecated';
|
||||
import { UnSupportFields } from './UnSupportFields';
|
||||
|
||||
const getInterfaceOptions = (data, type) => {
|
||||
const interfaceOptions = [];
|
||||
@ -29,6 +30,7 @@ const PreviewCom = (props) => {
|
||||
const [dataSource, setDataSource] = useState([]);
|
||||
const [sourceFields, setSourceFields] = useState([]);
|
||||
const [sourceCollections, setSourceCollections] = useState(sources);
|
||||
const [unsupportedFields, setUnsupportedFields] = useState([]);
|
||||
const field: any = useField();
|
||||
const form = useForm();
|
||||
const { getCollection, getInterface, getCollectionFields, getInheritCollections, getParentCollectionFields } =
|
||||
@ -101,6 +103,7 @@ const PreviewCom = (props) => {
|
||||
setDataSource(fieldsData);
|
||||
form.setValuesIn('sources', data.data?.sources);
|
||||
setSourceCollections(data.data?.sources);
|
||||
setUnsupportedFields(data?.data?.unsupportedFields);
|
||||
});
|
||||
}
|
||||
}).catch;
|
||||
@ -248,6 +251,7 @@ const PreviewCom = (props) => {
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
<UnSupportFields dataSource={unsupportedFields} />
|
||||
</Spin>
|
||||
);
|
||||
};
|
||||
|
@ -0,0 +1,32 @@
|
||||
import React from 'react';
|
||||
import { Table, Divider } from 'antd';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export const UnSupportFields = ({ dataSource }) => {
|
||||
const { t } = useTranslation();
|
||||
const columns = [
|
||||
{
|
||||
title: t('Field name'),
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
},
|
||||
{
|
||||
title: t('Field database type'),
|
||||
dataIndex: 'rawType',
|
||||
key: 'rawType',
|
||||
},
|
||||
];
|
||||
return (
|
||||
dataSource?.length > 0 && (
|
||||
<>
|
||||
<Divider plain orientation="left" orientationMargin="0">
|
||||
<h3>{t('Unknown field type')}</h3>
|
||||
</Divider>
|
||||
<div style={{ marginBottom: '15px' }}>
|
||||
{t('The following field types are not compatible and do not support output and display')}
|
||||
</div>
|
||||
<Table columns={columns} dataSource={dataSource} pagination={false} />
|
||||
</>
|
||||
)
|
||||
);
|
||||
};
|
@ -931,5 +931,7 @@
|
||||
"Automatically generate default values": "随机生成默认值",
|
||||
"Refresh data on close": "关闭后刷新数据",
|
||||
"Refresh data on action": "执行后刷新数据",
|
||||
"This variable has been deprecated and can be replaced with \"Current form\"": "该变量已被弃用,可以使用“当前表单”替代"
|
||||
"This variable has been deprecated and can be replaced with \"Current form\"": "该变量已被弃用,可以使用“当前表单”替代",
|
||||
"Unknown field type": "未知字段类型",
|
||||
"The following field types are not compatible and do not support output and display": "以下字段类型未适配,不支持输出和显示"
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ export class ViewFieldInference {
|
||||
const rawFields = [];
|
||||
|
||||
for (const [name, column] of Object.entries(columns)) {
|
||||
const inferResult: any = { name };
|
||||
const inferResult: any = { name, rawType: column.type };
|
||||
|
||||
const usage = columnUsage[name];
|
||||
|
||||
|
@ -165,14 +165,16 @@ SELECT * FROM numbers;
|
||||
expect(response.status).toBe(200);
|
||||
const data = response.body.data;
|
||||
|
||||
const nField = data.fields.find((field) => field.name === 'n');
|
||||
|
||||
if (app.db.inDialect('mysql')) {
|
||||
expect(data.fields.n.type).toBe('bigInt');
|
||||
expect(nField.type).toBe('bigInt');
|
||||
} else if (app.db.inDialect('postgres', 'mariadb')) {
|
||||
expect(data.fields.n.type).toBe('integer');
|
||||
expect(nField.type).toBe('integer');
|
||||
}
|
||||
});
|
||||
|
||||
it('should return possible types for json fields', async () => {
|
||||
it.skipIf(process.env['DB_DIALECT'] === 'sqlite')('should return possible types for json fields', async () => {
|
||||
if (app.db.inDialect('mariadb')) {
|
||||
// can not get json type from mariadb
|
||||
return;
|
||||
@ -198,11 +200,9 @@ SELECT * FROM numbers;
|
||||
expect(response.status).toBe(200);
|
||||
const data = response.body.data;
|
||||
|
||||
if (!app.db.inDialect('sqlite')) {
|
||||
expect(data.fields.json_field.type).toBe('json');
|
||||
}
|
||||
|
||||
expect(data.fields.json_field.possibleTypes).toBeTruthy();
|
||||
const jsonField = data.fields.find((field) => field.name === 'json_field');
|
||||
expect(jsonField.type).toBe('json');
|
||||
expect(jsonField.possibleTypes).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should not throw error when source collection destroyed', async () => {
|
||||
|
@ -7,14 +7,27 @@ export default {
|
||||
const { filterByTk, schema } = ctx.action.params;
|
||||
const db = ctx.app.db as Database;
|
||||
|
||||
const fields = await ViewFieldInference.inferFields({
|
||||
const fields = [];
|
||||
|
||||
const unsupportedFields = [];
|
||||
|
||||
const inferFields = await ViewFieldInference.inferFields({
|
||||
db,
|
||||
viewName: filterByTk,
|
||||
viewSchema: schema,
|
||||
});
|
||||
|
||||
for (const [_name, field] of Object.entries(inferFields)) {
|
||||
if (!field.type) {
|
||||
unsupportedFields.push(field);
|
||||
} else {
|
||||
fields.push(field);
|
||||
}
|
||||
}
|
||||
|
||||
ctx.body = {
|
||||
fields,
|
||||
unsupportedFields,
|
||||
sources: [
|
||||
...new Set(
|
||||
Object.values(fields)
|
||||
@ -62,9 +75,8 @@ export default {
|
||||
const limit = 1 * pageSize;
|
||||
|
||||
const sql = `SELECT *
|
||||
FROM ${ctx.app.db.utils.quoteTable(
|
||||
ctx.app.db.utils.addSchema(filterByTk, schema),
|
||||
)} LIMIT ${limit} OFFSET ${offset}`;
|
||||
FROM ${ctx.app.db.utils.quoteTable(ctx.app.db.utils.addSchema(filterByTk, schema))} LIMIT ${limit}
|
||||
OFFSET ${offset}`;
|
||||
|
||||
const rawValues = await ctx.app.db.sequelize.query(sql, { type: 'SELECT' });
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user