feat(database): support field get in view preview (#2482)
* feat: support field get in view preview * chore: test * refactor: dbViews fieldtypes * refactor: dbViews fieldtypes * refactor: dbViews fieldtypes * refactor: dbViews fieldtypes --------- Co-authored-by: katherinehhh <katherine_15995@163.com>
This commit is contained in:
parent
9d33da0437
commit
a625fc538d
@ -6,6 +6,7 @@ import { EllipsisWithTooltip, useCompile } from '../../../';
|
||||
import { useAPIClient } from '../../../api-client';
|
||||
import { useCollectionManager } from '../../hooks/useCollectionManager';
|
||||
|
||||
const mapFields = ['lineString', 'point', 'circle', 'polygon'];
|
||||
export const PreviewTable = (props) => {
|
||||
const { databaseView, schema, viewName, fields } = props;
|
||||
const [previewColumns, setPreviewColumns] = useState([]);
|
||||
@ -20,7 +21,7 @@ export const PreviewTable = (props) => {
|
||||
if (databaseView) {
|
||||
getPreviewData();
|
||||
}
|
||||
}, [databaseView]);
|
||||
}, [form.values.fields]);
|
||||
|
||||
useEffect(() => {
|
||||
const pColumns = formatPreviewColumns(fields);
|
||||
@ -28,10 +29,16 @@ export const PreviewTable = (props) => {
|
||||
}, [form.values.fields]);
|
||||
|
||||
const getPreviewData = () => {
|
||||
const fieldTypes = {};
|
||||
form.values.fields.map((v) => {
|
||||
if (mapFields.includes(v.type)) {
|
||||
fieldTypes[v.name] = v.type;
|
||||
}
|
||||
});
|
||||
setLoading(true);
|
||||
api
|
||||
.resource(`dbViews`)
|
||||
.query({ filterByTk: viewName, schema })
|
||||
.query({ filterByTk: viewName, schema, fieldTypes })
|
||||
.then(({ data }) => {
|
||||
if (data) {
|
||||
setLoading(false);
|
||||
@ -58,7 +65,13 @@ export const PreviewTable = (props) => {
|
||||
const objSchema: any = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
[item.name]: { ...schema, default: content, 'x-read-pretty': true, title: null },
|
||||
[item.name]: {
|
||||
name: `${item.name}`,
|
||||
'x-component': schema && fieldSource ? 'CollectionField' : 'Input',
|
||||
'x-read-pretty': true,
|
||||
'x-collection-field': fieldSource?.join('.'),
|
||||
default: content,
|
||||
},
|
||||
},
|
||||
};
|
||||
return (
|
||||
@ -98,7 +111,7 @@ export const PreviewTable = (props) => {
|
||||
columns={previewColumns}
|
||||
dataSource={previewData}
|
||||
scroll={{ x: 1000, y: 300 }}
|
||||
key={viewName}
|
||||
key={`${viewName}-preview`}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
|
@ -27,7 +27,7 @@ export const ReadPrettyInternalViewer: React.FC = observer(
|
||||
(props: any) => {
|
||||
const fieldSchema = useFieldSchema();
|
||||
const recordCtx = useRecord();
|
||||
const { enableLink } = fieldSchema['x-component-props'];
|
||||
const { enableLink } = fieldSchema['x-component-props'] || {};
|
||||
// value 做了转换,但 props.value 和原来 useField().value 的值不一致
|
||||
const field = useField();
|
||||
const fieldNames = useFieldNames(props);
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Database, Repository } from '@nocobase/database';
|
||||
import { Database, Repository, Field, DataTypes } from '@nocobase/database';
|
||||
import { MockServer } from '@nocobase/test';
|
||||
import { uid } from '@nocobase/utils';
|
||||
import { createApp } from '../index';
|
||||
@ -54,6 +54,73 @@ SELECT * FROM numbers;
|
||||
await app.destroy();
|
||||
});
|
||||
|
||||
it('should support preview field with getter', async () => {
|
||||
class TestField extends Field {
|
||||
get dataType() {
|
||||
return DataTypes.STRING;
|
||||
}
|
||||
|
||||
constructor(options: any, context: any) {
|
||||
const { name } = options;
|
||||
super(
|
||||
{
|
||||
get() {
|
||||
return 'test_' + this.getDataValue(name);
|
||||
},
|
||||
...options,
|
||||
},
|
||||
context,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
db.registerFieldTypes({
|
||||
test: TestField,
|
||||
});
|
||||
|
||||
const C1 = db.collection({
|
||||
name: 'c1',
|
||||
fields: [
|
||||
{
|
||||
type: 'test',
|
||||
name: 'test_field',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
await db.sync();
|
||||
|
||||
await C1.repository.create({
|
||||
values: {
|
||||
test_field: '1',
|
||||
},
|
||||
});
|
||||
|
||||
const c1 = await C1.repository.findOne();
|
||||
expect(c1.get('test_field')).toEqual('test_1');
|
||||
|
||||
// create view from C1
|
||||
const viewName = `test_view_${uid(6)}`;
|
||||
await db.sequelize.query(`DROP VIEW IF EXISTS ${viewName}`);
|
||||
|
||||
const createSQL = `CREATE VIEW ${viewName} AS SELECT * FROM ${C1.quotedTableName()}`;
|
||||
|
||||
await db.sequelize.query(createSQL);
|
||||
|
||||
const response = await agent.resource('dbViews').query({
|
||||
filterByTk: viewName,
|
||||
pageSize: 20,
|
||||
fieldTypes: {
|
||||
test_field: 'test',
|
||||
},
|
||||
});
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
const data = response.body.data;
|
||||
const firstRow = data[0];
|
||||
expect(firstRow.test_field).toEqual('test_1');
|
||||
});
|
||||
|
||||
it('should list views', async () => {
|
||||
const response = await agent.resource('dbViews').list();
|
||||
expect(response.status).toBe(200);
|
||||
|
@ -1,4 +1,4 @@
|
||||
import Database, { Repository, ViewCollection, ViewFieldInference } from '@nocobase/database';
|
||||
import Database, { Field, Repository, ViewCollection, ViewFieldInference, DataTypes } from '@nocobase/database';
|
||||
import Application from '@nocobase/server';
|
||||
import { uid } from '@nocobase/utils';
|
||||
import { createApp } from '../index';
|
||||
|
@ -56,7 +56,7 @@ export default {
|
||||
},
|
||||
|
||||
async query(ctx, next) {
|
||||
const { filterByTk, schema = 'public', page = 1, pageSize = 10 } = ctx.action.params;
|
||||
const { filterByTk, fieldTypes, schema = 'public', page = 1, pageSize = 10 } = ctx.action.params;
|
||||
|
||||
const offset = (page - 1) * pageSize;
|
||||
const limit = 1 * pageSize;
|
||||
@ -66,7 +66,34 @@ export default {
|
||||
ctx.app.db.utils.addSchema(filterByTk, schema),
|
||||
)} LIMIT ${limit} OFFSET ${offset}`;
|
||||
|
||||
ctx.body = await ctx.app.db.sequelize.query(sql, { type: 'SELECT' });
|
||||
const rawValues = await ctx.app.db.sequelize.query(sql, { type: 'SELECT' });
|
||||
|
||||
if (fieldTypes) {
|
||||
for (const raw of rawValues) {
|
||||
const fakeInstance = {
|
||||
dataValues: raw,
|
||||
getDataValue: (key) => raw[key],
|
||||
};
|
||||
|
||||
for (const fieldName of Object.keys(fieldTypes)) {
|
||||
const fieldType = fieldTypes[fieldName];
|
||||
const FieldClass = ctx.app.db.fieldTypes.get(fieldType);
|
||||
|
||||
const fieldOptions = new FieldClass(
|
||||
{ name: fieldName },
|
||||
{
|
||||
db: ctx.app.db,
|
||||
},
|
||||
).options;
|
||||
|
||||
if (fieldOptions.get) {
|
||||
const newValue = fieldOptions.get.apply(fakeInstance);
|
||||
raw[fieldName] = newValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ctx.body = rawValues;
|
||||
await next();
|
||||
},
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user