fix: 上游跟进, source id为null的情况,fix-source id null

#3917
This commit is contained in:
bai.jingfeng 2024-04-07 18:43:18 +08:00
parent 90b1beae5e
commit 37cc172d82
14 changed files with 73 additions and 91 deletions

View File

@ -15,10 +15,15 @@ export function pageArgsToLimitArgs(
} }
export function getRepositoryFromParams(ctx: Context) { export function getRepositoryFromParams(ctx: Context) {
const { resourceName, resourceOf } = ctx.action; const { resourceName, sourceId, actionName } = ctx.action;
if (resourceOf) { if (sourceId === '_' && ['get', 'list'].includes(actionName)) {
return ctx.db.getRepository<MultipleRelationRepository>(resourceName, resourceOf); const collection = ctx.db.getCollection(resourceName);
return ctx.db.getRepository<Repository>(collection.name);
}
if (sourceId) {
return ctx.db.getRepository<MultipleRelationRepository>(resourceName, sourceId);
} }
return ctx.db.getRepository<Repository>(resourceName); return ctx.db.getRepository<Repository>(resourceName);

View File

@ -11,13 +11,13 @@ import {
TableFieldResource, TableFieldResource,
WithoutTableFieldResource, WithoutTableFieldResource,
useCollectionManager, useCollectionManager,
useCollectionParentRecord,
useCollectionParentRecordData,
useCollectionRecord,
useDataBlockProps, useDataBlockProps,
useDataBlockRequest, useDataBlockRequest,
useDataBlockResource, useDataBlockResource,
useDesignable, useDesignable,
useCollectionParentRecord,
useCollectionParentRecordData,
useCollectionRecord,
useRecord, useRecord,
} from '../'; } from '../';
import { ACLCollectionProvider } from '../acl/ACLProvider'; import { ACLCollectionProvider } from '../acl/ACLProvider';
@ -29,8 +29,7 @@ import {
import { DataBlockCollector } from '../filter-provider/FilterProvider'; import { DataBlockCollector } from '../filter-provider/FilterProvider';
import { RecordProvider, useRecordIndex } from '../record-provider'; import { RecordProvider, useRecordIndex } from '../record-provider';
import { useAssociationNames } from './hooks'; import { useAssociationNames } from './hooks';
import { useDataBlockSourceId } from './hooks/useDataBlockSourceId'; import { useDataBlockParentRecord } from './hooks/useDataBlockSourceId';
import { useTemplateBlockContext } from './TemplateBlockProvider';
/** /**
* @deprecated * @deprecated
@ -197,16 +196,16 @@ export const useBlockContext = () => {
/** /**
* Schema * Schema
*/ */
const useCompatDataBlockSourceId = (props) => { const useCompatDataBlockParentRecord = (props) => {
const fieldSchema = useFieldSchema(); const fieldSchema = useFieldSchema();
// 如果存在 x-use-decorator-props说明是新版 Schema // 如果存在 x-use-decorator-props说明是新版 Schema
if (fieldSchema['x-use-decorator-props']) { if (fieldSchema['x-use-decorator-props']) {
return props.sourceId; return props.parentRecord;
} else { } else {
// 是否存在 x-use-decorator-props 是固定不变的,所以这里可以使用 hooks // 是否存在 x-use-decorator-props 是固定不变的,所以这里可以使用 hooks
// eslint-disable-next-line react-hooks/rules-of-hooks // eslint-disable-next-line react-hooks/rules-of-hooks
return useDataBlockSourceId(props); return useDataBlockParentRecord(props);
} }
}; };
@ -227,9 +226,8 @@ export const BlockProvider = (props: {
/** @deprecated */ /** @deprecated */
useParams?: any; useParams?: any;
}) => { }) => {
const { name, dataSource, association, useParams, parentRecord } = props; const { name, dataSource, useParams, parentRecord } = props;
const sourceId = useCompatDataBlockSourceId(props); const parentRecordFromHook = useCompatDataBlockParentRecord(props);
const { templateFinshed } = useTemplateBlockContext();
// 新版1.0)已弃用 useParams这里之所以继续保留是为了兼容旧版的 UISchema // 新版1.0)已弃用 useParams这里之所以继续保留是为了兼容旧版的 UISchema
const paramsFromHook = useParams?.(); const paramsFromHook = useParams?.();
@ -241,20 +239,12 @@ export const BlockProvider = (props: {
return { ...props.params, appends, ...paramsFromHook }; return { ...props.params, appends, ...paramsFromHook };
} }
return { ...props.params, ...paramsFromHook }; return { ...props.params, ...paramsFromHook };
}, [appends, paramsFromHook, props.params, templateFinshed]); }, [appends, paramsFromHook, props.params]);
const blockValue = useMemo(() => ({ name }), [name]); const blockValue = useMemo(() => ({ name }), [name]);
return ( return (
<BlockContext.Provider value={blockValue}> <BlockContext.Provider value={blockValue}>
<DataBlockProvider <DataBlockProvider {...(props as any)} params={params} parentRecord={parentRecord || parentRecordFromHook}>
{...(props as any)}
params={params}
sourceId={sourceId}
// 此处是针对树表格的 Add child 按钮优化的,因为点击 Add child 打开的表单中需要用到父级的数据;
// 但是当是关系区块时,在 DataBlockProvider 中会自动请求父级数据,所以这里不需要再传 parentRecord。
// 具体问题记录在这里https://nocobase.height.app/T-3235/description
parentRecord={association ? undefined : parentRecord}
>
<BlockRequestProvider_deprecated {...props} updateAssociationValues={updateAssociationValues} params={params}> <BlockRequestProvider_deprecated {...props} updateAssociationValues={updateAssociationValues} params={params}>
<DataBlockCollector {...props} params={params}> <DataBlockCollector {...props} params={params}>
{props.children} {props.children}

View File

@ -5,14 +5,13 @@ import {
useCollectionParentRecordData, useCollectionParentRecordData,
useCollectionRecordData, useCollectionRecordData,
} from '../..'; } from '../..';
import { useSourceKey } from '../../modules/blocks/useSourceKey';
/** /**
* @internal * @internal
* @deprecated * @deprecated
* Schema x-use-decorator-props sourceId * Schema x-use-decorator-props parentRecord
* *
* schema sourceId * schema parentRecord
* recordData parentRecordData ; schema * recordData parentRecordData ; schema
* `通过点击关系字段按钮打开的弹窗中创建的非关系字段区块``关系字段区块`使 hook * `通过点击关系字段按钮打开的弹窗中创建的非关系字段区块``关系字段区块`使 hook
* *
@ -21,12 +20,11 @@ import { useSourceKey } from '../../modules/blocks/useSourceKey';
* @param param0 * @param param0
* @returns * @returns
*/ */
export const useDataBlockSourceId = ({ association }: { association: string }) => { export const useDataBlockParentRecord = ({ association }: { association: string }) => {
const recordData = useCollectionRecordData(); const recordData = useCollectionRecordData();
const parentRecordData = useCollectionParentRecordData(); const parentRecordData = useCollectionParentRecordData();
const cm = useCollectionManager(); const cm = useCollectionManager();
const currentRecordCollection = useCollection<InheritanceCollectionMixin>(); const currentRecordCollection = useCollection<InheritanceCollectionMixin>();
const sourceKey = useSourceKey(association);
if (!association) return; if (!association) return;
@ -36,8 +34,8 @@ export const useDataBlockSourceId = ({ association }: { association: string }) =
currentRecordCollection.name === sourceCollection.name || currentRecordCollection.name === sourceCollection.name ||
currentRecordCollection.getParentCollectionsName?.().includes(sourceCollection.name) currentRecordCollection.getParentCollectionsName?.().includes(sourceCollection.name)
) { ) {
return recordData?.[sourceKey]; return recordData;
} }
return parentRecordData?.[sourceKey]; return parentRecordData;
}; };

View File

@ -25,6 +25,7 @@ export * from './collection-manager';
export * from './common'; export * from './common';
export * from './css-variable'; export * from './css-variable';
export * from './data-source';
export * from './document-title'; export * from './document-title';
export * from './filter-provider'; export * from './filter-provider';
export * from './flag-provider'; export * from './flag-provider';
@ -52,16 +53,16 @@ export * from './system-settings';
export * from './testUtils'; export * from './testUtils';
export * from './user'; export * from './user';
export * from './variables'; export * from './variables';
export * from './data-source';
export { withDynamicSchemaProps } from './application/hoc/withDynamicSchemaProps'; export { withDynamicSchemaProps } from './application/hoc/withDynamicSchemaProps';
export * from './modules/blocks/BlockSchemaToolbar'; export * from './modules/blocks/BlockSchemaToolbar';
export * from './modules/blocks/data-blocks/table';
export * from './modules/blocks/data-blocks/form';
export * from './modules/blocks/data-blocks/table-selector';
export * from './modules/blocks/data-blocks/details-multi/setDataLoadingModeSettingsItem'; export * from './modules/blocks/data-blocks/details-multi/setDataLoadingModeSettingsItem';
export * from './modules/blocks/useSourceIdCommon'; export * from './modules/blocks/data-blocks/form';
export * from './modules/blocks/data-blocks/table';
export * from './modules/blocks/data-blocks/table-selector';
export * from './modules/blocks/useParentRecordCommon';
export * as __UNSAFE__ from './unsafe'; export * as __UNSAFE__ from './unsafe';
export type { export type {

View File

@ -1,15 +1,15 @@
import { useSourceIdCommon } from '../../../useSourceIdCommon'; import { useParentRecordCommon } from '../../../useParentRecordCommon';
export function useDetailsWithPaginationDecoratorProps(props) { export function useDetailsWithPaginationDecoratorProps(props) {
let sourceId; let parentRecord;
// association 的值是固定不变的,所以可以在条件中使用 hooks // association 的值是固定不变的,所以可以在条件中使用 hooks
if (props.association) { if (props.association) {
// eslint-disable-next-line react-hooks/rules-of-hooks // eslint-disable-next-line react-hooks/rules-of-hooks
sourceId = useSourceIdCommon(props.association); parentRecord = useParentRecordCommon(props.association);
} }
return { return {
sourceId, parentRecord,
}; };
} }

View File

@ -4,7 +4,6 @@ import {
useCollectionParentRecordData, useCollectionParentRecordData,
useCollectionRecordData, useCollectionRecordData,
} from '../../../../../data-source/collection-record/CollectionRecordProvider'; } from '../../../../../data-source/collection-record/CollectionRecordProvider';
import { useSourceKey } from '../../../useSourceKey';
/** /**
* Current record Add block * Current record Add block
@ -13,31 +12,30 @@ import { useSourceKey } from '../../../useSourceKey';
*/ */
export function useDetailsDecoratorProps(props) { export function useDetailsDecoratorProps(props) {
const params = useParamsFromRecord(); const params = useParamsFromRecord();
let sourceId; let parentRecord;
// association 的值是固定不变的,所以可以在条件中使用 hooks // association 的值是固定不变的,所以可以在条件中使用 hooks
if (props.association) { if (props.association) {
// eslint-disable-next-line react-hooks/rules-of-hooks // eslint-disable-next-line react-hooks/rules-of-hooks
sourceId = useDetailsSourceId(props.association); parentRecord = useDetailsParentRecord(props.association);
} }
return { return {
params, params,
sourceId, parentRecord,
}; };
} }
export function useDetailsSourceId(association: string) { export function useDetailsParentRecord(association: string) {
const fieldSchema = useFieldSchema(); const fieldSchema = useFieldSchema();
const recordData = useCollectionRecordData(); const recordData = useCollectionRecordData();
const parentRecordData = useCollectionParentRecordData(); const parentRecordData = useCollectionParentRecordData();
const sourceKey = useSourceKey(association);
if (!association) return; if (!association) return;
if (fieldSchema['x-is-current']) { if (fieldSchema['x-is-current']) {
return parentRecordData?.[sourceKey]; return parentRecordData;
} }
return recordData?.[sourceKey]; return recordData;
} }

View File

@ -1,15 +1,15 @@
import { useSourceIdCommon } from '../../../useSourceIdCommon'; import { useParentRecordCommon } from '../../../useParentRecordCommon';
export function useCreateFormBlockDecoratorProps(props) { export function useCreateFormBlockDecoratorProps(props) {
let sourceId; let parentRecord;
// association 的值是固定不变的,所以这里可以使用 hooks // association 的值是固定不变的,所以这里可以使用 hooks
if (props.association) { if (props.association) {
// eslint-disable-next-line react-hooks/rules-of-hooks // eslint-disable-next-line react-hooks/rules-of-hooks
sourceId = useSourceIdCommon(props.association); parentRecord = useParentRecordCommon(props.association);
} }
return { return {
sourceId, parentRecord,
}; };
} }

View File

@ -1,20 +1,19 @@
import { useParamsFromRecord } from '../../../../../block-provider/BlockProvider'; import { useParamsFromRecord } from '../../../../../block-provider/BlockProvider';
import { useDetailsSourceId } from '../../details-single/hooks/useDetailsDecoratorProps'; import { useDetailsParentRecord } from '../../details-single/hooks/useDetailsDecoratorProps';
export function useEditFormBlockDecoratorProps(props) { export function useEditFormBlockDecoratorProps(props) {
const params = useFormBlockParams(); const params = useFormBlockParams();
let sourceId; let parentRecord;
// association 的值是固定不变的,所以这里可以使用 hooks // association 的值是固定不变的,所以这里可以使用 hooks
if (props.association) { if (props.association) {
// 复用详情区块的 sourceId 获取逻辑 // 复用详情区块的 sourceId 获取逻辑
// eslint-disable-next-line react-hooks/rules-of-hooks // eslint-disable-next-line react-hooks/rules-of-hooks
sourceId = useDetailsSourceId(props.association); parentRecord = useDetailsParentRecord(props.association);
} }
return { return {
params, params,
sourceId, parentRecord,
}; };
} }

View File

@ -1,18 +1,18 @@
import { useGridCardBlockParams } from './useGridCardBlockParams'; import { useGridCardBlockParams } from './useGridCardBlockParams';
import { useSourceIdCommon } from '../../../useSourceIdCommon'; import { useParentRecordCommon } from '../../../useParentRecordCommon';
export function useGridCardBlockDecoratorProps(props) { export function useGridCardBlockDecoratorProps(props) {
const params = useGridCardBlockParams(props); const params = useGridCardBlockParams(props);
let sourceId; let parentRecord;
// 因为 association 是固定的,所以可以在条件中使用 hooks // 因为 association 是固定的,所以可以在条件中使用 hooks
if (props.association) { if (props.association) {
// eslint-disable-next-line react-hooks/rules-of-hooks // eslint-disable-next-line react-hooks/rules-of-hooks
sourceId = useSourceIdCommon(props.association); parentRecord = useParentRecordCommon(props.association);
} }
return { return {
params, params,
sourceId, parentRecord,
}; };
} }

View File

@ -1,15 +1,15 @@
import { useSourceIdCommon } from '../../../useSourceIdCommon'; import { useParentRecordCommon } from '../../../useParentRecordCommon';
export function useListBlockDecoratorProps(props) { export function useListBlockDecoratorProps(props) {
let sourceId; let parentRecord;
// 因为 association 的值是固定的,所以这里可以使用 hooks // 因为 association 的值是固定的,所以这里可以使用 hooks
if (props.association) { if (props.association) {
// eslint-disable-next-line react-hooks/rules-of-hooks // eslint-disable-next-line react-hooks/rules-of-hooks
sourceId = useSourceIdCommon(props.association); parentRecord = useParentRecordCommon(props.association);
} }
return { return {
sourceId, parentRecord,
}; };
} }

View File

@ -1,15 +1,15 @@
import { useFieldSchema } from '@nocobase/schema'; import { useFieldSchema } from '@nocobase/schema';
import { useParsedFilter } from '../../../../../block-provider/hooks/useParsedFilter'; import { useParsedFilter } from '../../../../../block-provider/hooks/useParsedFilter';
import { useMemo } from 'react'; import { useMemo } from 'react';
import { useSourceIdCommon } from '../../../useSourceIdCommon'; import { useParentRecordCommon } from '../../../useParentRecordCommon';
export const useTableBlockDecoratorProps = (props) => { export const useTableBlockDecoratorProps = (props) => {
const params = useTableBlockParams(props); const params = useTableBlockParams(props);
const sourceId = useTableBlockSourceId(props); const parentRecord = useParentRecordCommon(props.association);
return { return {
params, params,
sourceId, parentRecord,
}; };
}; };
@ -37,15 +37,3 @@ export function useTableBlockParams(props) {
return paramsWithFilter; return paramsWithFilter;
}, [fieldSchema, parsedFilter, props.dragSort, props.params]); }, [fieldSchema, parsedFilter, props.dragSort, props.params]);
} }
function useTableBlockSourceId(props) {
let sourceId: string | undefined;
// 因为 association 是固定不变的,所以在条件中使用 hooks 是安全的
if (props.association) {
// eslint-disable-next-line react-hooks/rules-of-hooks
sourceId = useSourceIdCommon(props.association);
}
return sourceId;
}

View File

@ -1,5 +1,4 @@
import { useCollectionRecordData } from '../../data-source/collection-record/CollectionRecordProvider'; import { useCollectionRecordData } from '../../data-source/collection-record/CollectionRecordProvider';
import { useSourceKey } from './useSourceKey';
/** /**
* @internal * @internal
@ -7,11 +6,10 @@ import { useSourceKey } from './useSourceKey';
* @param association * @param association
* @returns * @returns
*/ */
export const useSourceIdCommon = (association: string) => { export const useParentRecordCommon = (association: string) => {
const recordData = useCollectionRecordData(); const recordData = useCollectionRecordData();
const sourceKey = useSourceKey(association);
if (!association) return; if (!association) return;
return recordData?.[sourceKey]; return recordData;
}; };

View File

@ -15,12 +15,17 @@ export function pageArgsToLimitArgs(
} }
export function getRepositoryFromParams(ctx: Context): IRepository { export function getRepositoryFromParams(ctx: Context): IRepository {
const { resourceName, resourceOf } = ctx.action; const { resourceName, sourceId, actionName } = ctx.action;
const dataSource: DataSource = ctx.dataSource; const dataSource: DataSource = ctx.dataSource;
if (resourceOf) { if (sourceId === '_' && ['get', 'list'].includes(actionName)) {
return dataSource.collectionManager.getRepository(resourceName, resourceOf); const collection = dataSource.collectionManager.getCollection(resourceName);
return dataSource.collectionManager.getRepository(collection.name);
}
if (sourceId) {
return dataSource.collectionManager.getRepository(resourceName, sourceId);
} }
return dataSource.collectionManager.getRepository(resourceName); return dataSource.collectionManager.getRepository(resourceName);

View File

@ -1,18 +1,18 @@
import { useSourceIdCommon } from '@nocobase/client'; import { useParentRecordCommon } from '@nocobase/client';
import { useCalendarBlockParams } from './useCalendarBlockParams'; import { useCalendarBlockParams } from './useCalendarBlockParams';
export function useCalendarBlockDecoratorProps(props) { export function useCalendarBlockDecoratorProps(props) {
const params = useCalendarBlockParams(props); const params = useCalendarBlockParams(props);
let sourceId: string; let parentRecord;
// 因为 association 是一个固定的值,所以可以在 hooks 中直接使用 // 因为 association 是一个固定的值,所以可以在 hooks 中直接使用
if (props.association) { if (props.association) {
// eslint-disable-next-line react-hooks/rules-of-hooks // eslint-disable-next-line react-hooks/rules-of-hooks
sourceId = useSourceIdCommon(props.association); parentRecord = useParentRecordCommon(props.association);
} }
return { return {
params, params,
sourceId, parentRecord,
}; };
} }