tachybase_todo/packages/client/src/collection-manager/ResourceActionProvider.tsx

87 lines
2.9 KiB
TypeScript
Raw Normal View History

2022-02-16 15:11:24 +08:00
import { Result } from 'ahooks/lib/useRequest/src/types';
import React, { createContext, useContext, useEffect } from 'react';
2022-02-18 02:05:42 +08:00
import { useCollectionManager } from '.';
2022-02-17 23:56:39 +08:00
import { CollectionProvider, useRecord } from '..';
import { useAPIClient, useRequest } from '../api-client';
2022-02-16 15:11:24 +08:00
export const ResourceActionContext = createContext<Result<any, any>>(null);
interface ResourceActionProviderProps {
type?: 'association' | 'collection';
2022-02-16 15:11:24 +08:00
request?: any;
uid?: string;
}
const ResourceContext = createContext<any>(null);
const CollectionResourceActionProvider = (props) => {
2022-02-18 02:05:42 +08:00
let { collection, request, uid } = props;
const { get } = useCollectionManager();
const api = useAPIClient();
2022-02-18 02:05:42 +08:00
const service = useRequest(request, { uid });
const resource = api.resource(request.resource);
2022-02-18 02:05:42 +08:00
if (typeof collection === 'string') {
collection = get(collection);
}
if (!collection) {
return null;
}
return (
<ResourceContext.Provider value={{ type: 'collection', resource, collection }}>
2022-02-17 23:56:39 +08:00
<ResourceActionContext.Provider value={service}>
<CollectionProvider collection={collection}>{props.children}</CollectionProvider>
</ResourceActionContext.Provider>
</ResourceContext.Provider>
);
};
const AssociationResourceActionProvider = (props) => {
2022-02-18 02:05:42 +08:00
let { collection, association, request, uid } = props;
const { get } = useCollectionManager();
const api = useAPIClient();
const record = useRecord();
const resourceOf = record[association.sourceKey];
2022-02-18 02:05:42 +08:00
const service = useRequest({ resourceOf, ...request }, { uid });
const resource = api.resource(request.resource, resourceOf);
2022-02-18 02:05:42 +08:00
if (typeof collection === 'string') {
collection = get(collection);
}
if (!collection) {
return null;
}
return (
<ResourceContext.Provider value={{ type: 'association', resource, association }}>
2022-02-17 23:56:39 +08:00
<ResourceActionContext.Provider value={service}>
<CollectionProvider collection={collection}>{props.children}</CollectionProvider>
</ResourceActionContext.Provider>
</ResourceContext.Provider>
);
};
export const ResourceActionProvider: React.FC<ResourceActionProviderProps> = (props) => {
const { request } = props;
if (request?.resource?.includes('.')) {
return <AssociationResourceActionProvider {...props} />;
}
return <CollectionResourceActionProvider {...props} />;
2022-02-16 15:11:24 +08:00
};
export const useResourceActionContext = () => {
return useContext(ResourceActionContext);
};
export const useDataSourceFromRAC = (options: any) => {
const service = useContext(ResourceActionContext);
useEffect(() => {
if (!service.loading) {
options?.onSuccess(service.data);
}
}, [service.loading]);
return service;
};
export const useResourceContext = () => {
const { type, resource, collection, association } = useContext(ResourceContext);
return { type, resource, collection, association, targetKey: association?.targetKey || collection?.targetKey || 'id' };
};