fix: preload relational data (#1847)
* fix: getNesterAppends filter bug * fix: associationSelect * fix: associationSelect * fix: associationSelect * fix: getAssociationAppends * fix: sub-form collection context * refactor: code improve * refactor: code improve * refactor: code improve * refactor: code improve * refactor: code improve * fix: appends * fix: sub-table-appends * fix: undefine id * fix: sub-table appends * fix: sub-table-appends * fix: sub-table-appends * fix: association field appends * fix: association field appends * fix: association field appends * fix: sub-table appends * fix: runWhenParamsChanged * fix: runWhenParamsChanged * chore: eager loading tree * feat: load eager loading tree * fix: support mutiple row * fix: support blockTemplate appends * feat: merge stage of eager loading * feat: merge stage of belongs to * feat: merge stage of has one * fix: dynamic appends not support template schema * feat: merge stage of belongs to many * chore: test * chore: print tree * chore: using eager loading tree in repository find * fix: empty ids load * fix: belongs to many query * fix: load belongs to association * fix: eager load data accessor * fix: has many * fix: test * fix: useAssociationNames * fix: filter with appends * chore: remove handle appends query * chore: console.log * chore: console.log * fix: test * fix: support template block schema * fix: sub-nester-appends --------- Co-authored-by: Chareice <chareice@live.com>
This commit is contained in:
parent
eac034cb23
commit
cb2feb304d
@ -53,14 +53,13 @@ const useResource = (props: UseResourceProps) => {
|
|||||||
const api = useAPIClient();
|
const api = useAPIClient();
|
||||||
const association = useAssociation(props);
|
const association = useAssociation(props);
|
||||||
const sourceId = useSourceId?.();
|
const sourceId = useSourceId?.();
|
||||||
|
|
||||||
const field = useField<Field>();
|
const field = useField<Field>();
|
||||||
if (block === 'TableField') {
|
if (block === 'TableField') {
|
||||||
const options = {
|
const options = {
|
||||||
field,
|
field,
|
||||||
api,
|
api,
|
||||||
resource,
|
resource,
|
||||||
sourceId: sourceId || record[association?.sourceKey || 'id'],
|
sourceId: sourceId || record[association?.sourceKey || 'id'] || record?.__parent?.[association?.sourceKey || 'id'],
|
||||||
};
|
};
|
||||||
return new TableFieldResource(options);
|
return new TableFieldResource(options);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { Schema, SchemaExpressionScopeContext, useField, useFieldSchema, useForm } from '@formily/react';
|
import { Schema, SchemaExpressionScopeContext, useField, useFieldSchema, useForm } from '@formily/react';
|
||||||
import { parse } from '@nocobase/utils/client';
|
import { parse } from '@nocobase/utils/client';
|
||||||
import { Modal, message } from 'antd';
|
import { Modal, message } from 'antd';
|
||||||
import { cloneDeep } from 'lodash';
|
import { cloneDeep, uniq } from 'lodash';
|
||||||
import get from 'lodash/get';
|
import get from 'lodash/get';
|
||||||
import omit from 'lodash/omit';
|
import omit from 'lodash/omit';
|
||||||
import { ChangeEvent, useContext, useEffect } from 'react';
|
import { ChangeEvent, useContext, useEffect } from 'react';
|
||||||
@ -21,6 +21,7 @@ import { useBlockRequestContext, useFilterByTk } from '../BlockProvider';
|
|||||||
import { useDetailsBlockContext } from '../DetailsBlockProvider';
|
import { useDetailsBlockContext } from '../DetailsBlockProvider';
|
||||||
import { mergeFilter } from '../SharedFilterProvider';
|
import { mergeFilter } from '../SharedFilterProvider';
|
||||||
import { TableFieldResource } from '../TableFieldProvider';
|
import { TableFieldResource } from '../TableFieldProvider';
|
||||||
|
import { useSchemaTemplateManager } from '../../schema-templates';
|
||||||
|
|
||||||
export const usePickActionProps = () => {
|
export const usePickActionProps = () => {
|
||||||
const form = useForm();
|
const form = useForm();
|
||||||
@ -1072,22 +1073,24 @@ export const useAssociationFilterBlockProps = () => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useAssociationNames = (collection) => {
|
const getTemplateSchema = (schema) => {
|
||||||
const { getCollectionFields, getCollectionJoinField } = useCollectionManager();
|
const conf = {
|
||||||
const { getField } = useCollection();
|
url: `/uiSchemas:getJsonSchema/${schema?.uid}`,
|
||||||
const collectionFields = getCollectionFields(collection);
|
};
|
||||||
const associationFields = new Set();
|
const { data, loading, run } = useRequest(conf, { manual: true });
|
||||||
for (const collectionField of collectionFields) {
|
if (loading) {
|
||||||
if (collectionField.target) {
|
|
||||||
associationFields.add(collectionField.name);
|
|
||||||
const fields = getCollectionFields(collectionField.target);
|
|
||||||
for (const field of fields) {
|
|
||||||
if (field.target) {
|
|
||||||
associationFields.add(`${collectionField.name}.${field.name}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
useEffect(() => {
|
||||||
|
if (schema?.uid) {
|
||||||
|
run();
|
||||||
|
}
|
||||||
|
}, [schema?.uid]);
|
||||||
|
return schema?.uid ? new Schema(data?.data) : null;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useAssociationNames = (collection) => {
|
||||||
|
const { getCollectionJoinField } = useCollectionManager();
|
||||||
|
const { getTemplateById } = useSchemaTemplateManager();
|
||||||
const fieldSchema = useFieldSchema();
|
const fieldSchema = useFieldSchema();
|
||||||
const associationValues = [];
|
const associationValues = [];
|
||||||
const formSchema = fieldSchema.reduceProperties((buf, schema) => {
|
const formSchema = fieldSchema.reduceProperties((buf, schema) => {
|
||||||
@ -1097,26 +1100,37 @@ export const useAssociationNames = (collection) => {
|
|||||||
return buf;
|
return buf;
|
||||||
}, new Schema({}));
|
}, new Schema({}));
|
||||||
|
|
||||||
|
const templateSchema = formSchema.reduceProperties((buf, schema) => {
|
||||||
|
if (schema['x-component'] === 'BlockTemplate') {
|
||||||
|
return schema;
|
||||||
|
}
|
||||||
|
return buf;
|
||||||
|
}, null);
|
||||||
|
|
||||||
const getAssociationAppends = (schema, arr = []) => {
|
const getAssociationAppends = (schema, arr = []) => {
|
||||||
const data = schema.reduceProperties((buf, s) => {
|
const data = schema.reduceProperties((buf, s) => {
|
||||||
const collectionfield =
|
const collectionfield = s['x-collection-field'] && getCollectionJoinField(s['x-collection-field']);
|
||||||
getField(s.name) || (s['x-collection-field'] && getCollectionJoinField(s['x-collection-field']));
|
if (
|
||||||
if (collectionfield && ['hasOne', 'hasMany', 'belongsTo', 'belongsToMany'].includes(collectionfield.type)) {
|
collectionfield &&
|
||||||
|
['hasOne', 'hasMany', 'belongsTo', 'belongsToMany'].includes(collectionfield.type) &&
|
||||||
|
s['x-component'] !== 'TableField'
|
||||||
|
) {
|
||||||
|
buf.push(s.name);
|
||||||
if (['Nester', 'SubTable'].includes(s['x-component-props']?.mode)) {
|
if (['Nester', 'SubTable'].includes(s['x-component-props']?.mode)) {
|
||||||
associationValues.push(s.name);
|
associationValues.push(s.name);
|
||||||
}
|
}
|
||||||
|
if (s['x-component-props'].mode === 'Nester') {
|
||||||
buf.push(s.name);
|
|
||||||
if (s['x-component-props'].mode === 'Nester' || s['x-component'] === 'TableField') {
|
|
||||||
return getAssociationAppends(s, buf);
|
return getAssociationAppends(s, buf);
|
||||||
}
|
}
|
||||||
return buf;
|
return buf;
|
||||||
} else {
|
} else {
|
||||||
if (s['x-component'] === 'Grid' || s['x-component'] === 'TableV2') {
|
if (s['x-component'] === 'Grid.Row') {
|
||||||
const kk = buf?.concat?.();
|
const kk = buf?.concat?.();
|
||||||
return getNesterAppends(s, kk || []);
|
return getNesterAppends(s, kk || []);
|
||||||
} else {
|
} else {
|
||||||
return !s['x-component']?.includes('Action.') && getAssociationAppends(s, buf);
|
return !s['x-component']?.includes('Action.') && s['x-component'] !== 'TableField'
|
||||||
|
? getAssociationAppends(s, buf)
|
||||||
|
: buf;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, arr);
|
}, arr);
|
||||||
@ -1130,15 +1144,24 @@ export const useAssociationNames = (collection) => {
|
|||||||
if (Array.isArray(list[i])) {
|
if (Array.isArray(list[i])) {
|
||||||
`${prefix}` !== `${list[i][0]}` && flattenHelper(list[i], `${prefix}.${list[i][0]}`);
|
`${prefix}` !== `${list[i][0]}` && flattenHelper(list[i], `${prefix}.${list[i][0]}`);
|
||||||
} else {
|
} else {
|
||||||
const str = prefix.replaceAll(`${list[i]}`, '').replace('..', '.').trim();
|
const searchTerm = `.${list[i]}`;
|
||||||
!list.includes(str) && flattenedList.push(`${str}${list[i]}`);
|
const lastIndex = prefix.lastIndexOf(searchTerm);
|
||||||
|
let str = '';
|
||||||
|
if (lastIndex !== -1) {
|
||||||
|
str = prefix.slice(0, lastIndex) + prefix.slice(lastIndex + searchTerm.length);
|
||||||
|
}
|
||||||
|
if (!str) {
|
||||||
|
!list.includes(str) && flattenedList.push(`${list[i]}`);
|
||||||
|
} else {
|
||||||
|
!list.includes(str) ? flattenedList.push(`${str}.${list[i]}`) : flattenedList.push(str);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (let i = 0; i < nestedList.length; i++) {
|
for (let i = 0; i < nestedList.length; i++) {
|
||||||
flattenHelper(nestedList[i], nestedList[i][0]);
|
flattenHelper(nestedList[i], nestedList[i][0]);
|
||||||
}
|
}
|
||||||
return flattenedList.filter((obj) => !obj.startsWith('.'));
|
return uniq(flattenedList.filter((obj) => !obj?.startsWith('.')));
|
||||||
}
|
}
|
||||||
const getNesterAppends = (gridSchema, data) => {
|
const getNesterAppends = (gridSchema, data) => {
|
||||||
gridSchema.reduceProperties((buf, s) => {
|
gridSchema.reduceProperties((buf, s) => {
|
||||||
@ -1147,8 +1170,18 @@ export const useAssociationNames = (collection) => {
|
|||||||
}, data);
|
}, data);
|
||||||
return data.filter((g) => g.length);
|
return data.filter((g) => g.length);
|
||||||
};
|
};
|
||||||
const data = getAssociationAppends(formSchema);
|
|
||||||
const associations = data.filter((g) => g.length);
|
const template = getTemplateById(templateSchema?.['x-component-props']?.templateId);
|
||||||
const appends = flattenNestedList(associations);
|
const schema = getTemplateSchema(template);
|
||||||
return { appends, updateAssociationValues: appends.filter((v) => associationValues.includes(v)) };
|
if (schema) {
|
||||||
|
const associations = getAssociationAppends(schema);
|
||||||
|
const appends = flattenNestedList(associations);
|
||||||
|
console.log(appends, associations);
|
||||||
|
return { appends, updateAssociationValues: appends.filter((v) => associationValues.includes(v)) };
|
||||||
|
}
|
||||||
|
if (!schema) {
|
||||||
|
const associations = getAssociationAppends(formSchema);
|
||||||
|
const appends = flattenNestedList(associations);
|
||||||
|
return { appends, updateAssociationValues: appends.filter((v) => associationValues.includes(v)) };
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user