This commit is contained in:
dream2023 2023-12-25 16:11:51 +08:00
parent d8a397d452
commit e7e7a28cfe
4 changed files with 47 additions and 13 deletions

View File

@ -34,8 +34,8 @@ class CollectionManagerV2 {
getCollections(ns?: string, predicate?: (collection: CollectionV2) => boolean): CollectionV2[]
async getCollection(path: string, options?: GetCollectionOptions): Promise<CollectionV2 | undefined>
async getCollectionName(path: string, options?: GetCollectionOptions): Promise<string | undefined>;
removeCollection(path: string, options?: GetCollectionOptions): void;
getCollectionField(path: string, options?: GetCollectionOptions): CollectionFieldOptions | undefined;
async removeCollection(path: string, options?: GetCollectionOptions): void;
async getCollectionField(path: string, options?: GetCollectionOptions): Promise<CollectionFieldOptions | undefined>;
addCollectionFieldInterfaces(interfaces:CollectionFieldInterfaceV2[] | CollectionFieldInterfaceOptions[]): void;
getCollectionFieldInterfaces(): CollectionFieldInterfaceV2[]
@ -461,7 +461,7 @@ collectionManager.getCollectionName('users.profileId'); // 'profiles'
```tsx | pure
class CollectionManagerV2 {
removeCollection(path: string, options?: GetCollectionOptions): void;
async removeCollection(path: string, options?: GetCollectionOptions): void;
}
```
@ -479,7 +479,7 @@ collectionManager.removeCollection('users');
```tsx | pure
class CollectionManagerV2 {
getCollectionField(path: string, options?: GetCollectionOptions): CollectionFieldOptions | undefined;
async getCollectionField(path: string, options?: GetCollectionOptions): CollectionFieldOptions | undefined;
}
```

View File

@ -1,8 +1,10 @@
import React, { FC, ReactNode } from 'react';
import React, { FC, ReactNode, useEffect, useState } from 'react';
import { CollectionProviderV2 } from './CollectionProvider';
import { CollectionFieldProviderV2 } from './CollectionFieldProvider';
import { useCollectionManagerV2 } from './CollectionManagerProvider';
import { Spin } from 'antd';
import { CollectionV2 } from './Collection';
export interface AssociationProviderProps {
ns?: string;
@ -14,11 +16,30 @@ export const AssociationProviderV2: FC<AssociationProviderProps> = (props) => {
const { name, ns, children } = props;
const collectionManager = useCollectionManagerV2();
const [loading, setLoading] = useState(false);
const [collectionName, setCollectionName] = useState<string>();
useEffect(() => {
const load = async () => {
setLoading(true);
try {
const res = await collectionManager.getCollectionName(name, { ns });
setCollectionName(res);
setLoading(false);
} catch (error) {
console.error(error);
setLoading(false);
}
};
load();
}, [collectionManager, name, ns]);
if (loading) return <Spin />;
return (
<CollectionProviderV2 name={name.split('.')[0]} ns={ns}>
<CollectionFieldProviderV2 name={name}>
<CollectionProviderV2 name={collectionManager.getCollectionName(name)} ns={ns}>
<CollectionProviderV2 name={collectionName} ns={ns}>
{children}
</CollectionProviderV2>
</CollectionFieldProviderV2>

View File

@ -99,7 +99,7 @@ export class CollectionManagerV2 {
this.checkNamespace(ns);
if (path.split('.').length > 1) {
// 获取到关联字段
const associationField = this.getCollectionField(path);
const associationField = await this.getCollectionField(path);
return this.getCollection(associationField.target, { ns });
}
@ -109,12 +109,12 @@ export class CollectionManagerV2 {
const res = await this.getCollection(path, options);
return res?.name;
}
removeCollection(path: string, options: GetCollectionOptions = {}) {
async removeCollection(path: string, options: GetCollectionOptions = {}) {
const { ns = DEFAULT_COLLECTION_NAMESPACE_NAME } = options;
this.checkNamespace(ns);
if (path.split('.').length > 1) {
// 获取到关联字段
const associationField = this.getCollectionField(path);
const associationField = await this.getCollectionField(path);
return this.removeCollection(associationField.target, { ns });
}
@ -127,7 +127,10 @@ export class CollectionManagerV2 {
* getCollection('users.username'); // 获取 users 表的 username 字段
* getCollection('a.b.c'); // 获取 a 表的 b 字段的关联表,然后 b.target 表对应的 c 字段
*/
getCollectionField(path: string, options: GetCollectionOptions = {}): CollectionFieldOptions | undefined {
async getCollectionField(
path: string,
options: GetCollectionOptions = {},
): Promise<CollectionFieldOptions | undefined> {
const arr = path.split('.');
if (arr.length < 2) {
throw new Error(`[@nocobase/client]: CollectionManager.getCollectionField() path "${path}" is invalid`);
@ -135,7 +138,7 @@ export class CollectionManagerV2 {
const [collectionName, fieldName, ...otherFieldNames] = path.split('.');
const { ns = DEFAULT_COLLECTION_NAMESPACE_NAME } = options || {};
this.checkNamespace(ns);
const collection = this.getCollection(collectionName, { ns });
const collection = await this.getCollection(collectionName, { ns });
if (!collection) {
return;
}

View File

@ -1,6 +1,7 @@
import React, { FC, ReactNode, createContext, useContext, useMemo } from 'react';
import React, { FC, ReactNode, createContext, useContext, useEffect, useMemo, useState } from 'react';
import type { CollectionManagerV2, GetCollectionOptions } from './CollectionManager';
import type { CollectionV2 } from './Collection';
import { CollectionFieldOptions } from '../../collection-manager';
export const CollectionManagerContextV2 = createContext<CollectionManagerV2>(null);
CollectionManagerContextV2.displayName = 'CollectionManagerContextV2';
@ -32,6 +33,15 @@ export const useCollectionsV2 = (ns?: string, predicate?: (collection: Collectio
export const useCollectionFieldByPathV2 = (path: string, options?: GetCollectionOptions) => {
const collectionManager = useCollectionManagerV2();
const field = useMemo(() => collectionManager.getCollectionField(path, options), [collectionManager, path, options]);
const [field, setField] = useState<CollectionFieldOptions>();
useEffect(() => {
async function load() {
const field = await collectionManager.getCollectionField(path, options);
setField(field);
}
load();
}, [collectionManager, path, options]);
return field;
};