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:
ChengLei Shao 2024-04-26 10:11:47 +08:00 committed by GitHub
parent 4165d8baae
commit 7748a33138
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 66 additions and 15 deletions

View File

@ -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,
}}
/>

View File

@ -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>
);
};

View File

@ -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} />
</>
)
);
};

View File

@ -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": "以下字段类型未适配,不支持输出和显示"
}

View File

@ -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];

View File

@ -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 () => {

View File

@ -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' });