Revert "Revert "fix: add displayName (#3628)""
This reverts commit 58e2fd6ea6
.
This commit is contained in:
parent
fbe0c14920
commit
350c0ac1f4
@ -14,6 +14,7 @@ import { useApp } from '../application';
|
|||||||
import { useDataSourceKey } from '../data-source/data-source/DataSourceProvider';
|
import { useDataSourceKey } from '../data-source/data-source/DataSourceProvider';
|
||||||
|
|
||||||
export const ACLContext = createContext<any>({});
|
export const ACLContext = createContext<any>({});
|
||||||
|
ACLContext.displayName = 'ACLContext';
|
||||||
|
|
||||||
// TODO: delete this,replace by `ACLPlugin`
|
// TODO: delete this,replace by `ACLPlugin`
|
||||||
export const ACLProvider = (props) => {
|
export const ACLProvider = (props) => {
|
||||||
@ -90,6 +91,7 @@ export const useACLContext = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const ACLActionParamsContext = createContext<any>({});
|
export const ACLActionParamsContext = createContext<any>({});
|
||||||
|
ACLActionParamsContext.displayName = 'ACLActionParamsContext';
|
||||||
|
|
||||||
export const useACLRolesCheck = () => {
|
export const useACLRolesCheck = () => {
|
||||||
const ctx = useContext(ACLContext);
|
const ctx = useContext(ACLContext);
|
||||||
|
@ -31,6 +31,7 @@ const getChildrenKeys = (data = [], arr = []) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const SettingMenuContext = createContext(null);
|
const SettingMenuContext = createContext(null);
|
||||||
|
SettingMenuContext.displayName = 'SettingMenuContext';
|
||||||
|
|
||||||
export const SettingCenterProvider = (props) => {
|
export const SettingCenterProvider = (props) => {
|
||||||
const configureItems = useContext(SettingsCenterContext);
|
const configureItems = useContext(SettingsCenterContext);
|
||||||
|
@ -4,6 +4,7 @@ import { useRequest } from '../../api-client';
|
|||||||
import { useAdminSchemaUid } from '../../hooks';
|
import { useAdminSchemaUid } from '../../hooks';
|
||||||
|
|
||||||
const MenuItemsContext = createContext(null);
|
const MenuItemsContext = createContext(null);
|
||||||
|
MenuItemsContext.displayName = 'MenuItemsContext';
|
||||||
|
|
||||||
export const toItems = (properties = {}) => {
|
export const toItems = (properties = {}) => {
|
||||||
const items = [];
|
const items = [];
|
||||||
|
@ -14,6 +14,7 @@ export const SettingCenterPermissionProvider = (props) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const PermissionContext = createContext<any>(null);
|
export const PermissionContext = createContext<any>(null);
|
||||||
|
PermissionContext.displayName = 'PermissionContext';
|
||||||
|
|
||||||
export const PermissionProvider = (props) => {
|
export const PermissionProvider = (props) => {
|
||||||
const api = useAPIClient();
|
const api = useAPIClient();
|
||||||
|
@ -7,6 +7,7 @@ import { PermissionProvider, SettingCenterPermissionProvider } from '../Configur
|
|||||||
import { roleSchema } from './schemas/roles';
|
import { roleSchema } from './schemas/roles';
|
||||||
|
|
||||||
const AvailableActionsContext = createContext([]);
|
const AvailableActionsContext = createContext([]);
|
||||||
|
AvailableActionsContext.displayName = 'AvailableActionsContext';
|
||||||
|
|
||||||
const AvailableActionsProver: React.FC = (props) => {
|
const AvailableActionsProver: React.FC = (props) => {
|
||||||
const { data, loading } = useRequest<{
|
const { data, loading } = useRequest<{
|
||||||
|
@ -22,6 +22,7 @@ const toActionMap = (arr: any[]) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const RoleResourceCollectionContext = createContext<any>({});
|
export const RoleResourceCollectionContext = createContext<any>({});
|
||||||
|
RoleResourceCollectionContext.displayName = 'RoleResourceCollectionContext';
|
||||||
|
|
||||||
export const RolesResourcesActions = connect((props) => {
|
export const RolesResourcesActions = connect((props) => {
|
||||||
const { styles } = useStyles();
|
const { styles } = useStyles();
|
||||||
|
@ -4,6 +4,7 @@ import { FormProvider, SchemaComponent } from '../../schema-component';
|
|||||||
import { scopesSchema } from './schemas/scopes';
|
import { scopesSchema } from './schemas/scopes';
|
||||||
|
|
||||||
const RolesResourcesScopesSelectedRowKeysContext = createContext(null);
|
const RolesResourcesScopesSelectedRowKeysContext = createContext(null);
|
||||||
|
RolesResourcesScopesSelectedRowKeysContext.displayName = 'RolesResourcesScopesSelectedRowKeysContext';
|
||||||
|
|
||||||
const RolesResourcesScopesSelectedRowKeysProvider: React.FC = (props) => {
|
const RolesResourcesScopesSelectedRowKeysProvider: React.FC = (props) => {
|
||||||
const [keys, setKeys] = useState([]);
|
const [keys, setKeys] = useState([]);
|
||||||
|
@ -7,6 +7,7 @@ import { Plugin } from '../application/Plugin';
|
|||||||
import { loadConstrueLocale } from './loadConstrueLocale';
|
import { loadConstrueLocale } from './loadConstrueLocale';
|
||||||
|
|
||||||
export const AppLangContext = createContext<any>({});
|
export const AppLangContext = createContext<any>({});
|
||||||
|
AppLangContext.displayName = 'AppLangContext';
|
||||||
|
|
||||||
export const useAppLangContext = () => {
|
export const useAppLangContext = () => {
|
||||||
return useContext(AppLangContext);
|
return useContext(AppLangContext);
|
||||||
|
@ -2,3 +2,4 @@ import { createContext } from 'react';
|
|||||||
import { APIClient } from './APIClient';
|
import { APIClient } from './APIClient';
|
||||||
|
|
||||||
export const APIClientContext = createContext<APIClient>(new APIClient());
|
export const APIClientContext = createContext<APIClient>(new APIClient());
|
||||||
|
APIClientContext.displayName = 'APIClientContext';
|
||||||
|
@ -3,6 +3,7 @@ import { useRequest } from '../api-client';
|
|||||||
import { useAppSpin } from '../application/hooks/useAppSpin';
|
import { useAppSpin } from '../application/hooks/useAppSpin';
|
||||||
|
|
||||||
export const CurrentAppInfoContext = createContext(null);
|
export const CurrentAppInfoContext = createContext(null);
|
||||||
|
CurrentAppInfoContext.displayName = 'CurrentAppInfoContext';
|
||||||
|
|
||||||
export const useCurrentAppInfo = () => {
|
export const useCurrentAppInfo = () => {
|
||||||
return useContext<{
|
return useContext<{
|
||||||
|
@ -45,6 +45,7 @@ export class PluginSettingsManager {
|
|||||||
protected settings: Record<string, PluginSettingOptions> = {};
|
protected settings: Record<string, PluginSettingOptions> = {};
|
||||||
protected aclSnippets: string[] = [];
|
protected aclSnippets: string[] = [];
|
||||||
public app: Application;
|
public app: Application;
|
||||||
|
private cachedList = {};
|
||||||
|
|
||||||
constructor(_pluginSettings: Record<string, PluginSettingOptions>, app: Application) {
|
constructor(_pluginSettings: Record<string, PluginSettingOptions>, app: Application) {
|
||||||
this.app = app;
|
this.app = app;
|
||||||
@ -141,11 +142,16 @@ export class PluginSettingsManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getList(filterAuth = true): PluginSettingsPageType[] {
|
getList(filterAuth = true): PluginSettingsPageType[] {
|
||||||
return Array.from(new Set(Object.values(this.settings).map((item) => item.topLevelName)))
|
const cacheKey = JSON.stringify(filterAuth);
|
||||||
|
if (this.cachedList[cacheKey]) return this.cachedList[cacheKey];
|
||||||
|
|
||||||
|
return (this.cachedList[cacheKey] = Array.from(
|
||||||
|
new Set(Object.values(this.settings).map((item) => item.topLevelName)),
|
||||||
|
)
|
||||||
.sort((a, b) => a.localeCompare(b)) // sort by name
|
.sort((a, b) => a.localeCompare(b)) // sort by name
|
||||||
.map((name) => this.get(name, filterAuth))
|
.map((name) => this.get(name, filterAuth))
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
.sort((a, b) => (a.sort || 0) - (b.sort || 0));
|
.sort((a, b) => (a.sort || 0) - (b.sort || 0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
getAclSnippets() {
|
getAclSnippets() {
|
||||||
|
@ -8,32 +8,35 @@ export interface AppComponentProps {
|
|||||||
app: Application;
|
app: Application;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const AppComponent: FC<AppComponentProps> = observer((props) => {
|
export const AppComponent: FC<AppComponentProps> = observer(
|
||||||
const { app } = props;
|
(props) => {
|
||||||
const handleErrors = useCallback((error: Error, info: { componentStack: string }) => {
|
const { app } = props;
|
||||||
console.error(error);
|
const handleErrors = useCallback((error: Error, info: { componentStack: string }) => {
|
||||||
const err = new Error();
|
console.error(error);
|
||||||
err.stack = info.componentStack.trim();
|
const err = new Error();
|
||||||
console.error(err);
|
err.stack = info.componentStack.trim();
|
||||||
}, []);
|
console.error(err);
|
||||||
useEffect(() => {
|
}, []);
|
||||||
app.load();
|
useEffect(() => {
|
||||||
}, [app]);
|
app.load();
|
||||||
const AppError = app.getComponent('AppError');
|
}, [app]);
|
||||||
if (app.loading) return app.renderComponent('AppSpin', { app });
|
const AppError = app.getComponent('AppError');
|
||||||
if (!app.maintained && app.maintaining) return app.renderComponent('AppMaintaining', { app });
|
if (app.loading) return app.renderComponent('AppSpin', { app });
|
||||||
if (app.error?.code === 'LOAD_ERROR' || app.error?.code === 'APP_ERROR') {
|
if (!app.maintained && app.maintaining) return app.renderComponent('AppMaintaining', { app });
|
||||||
return <AppError app={app} error={app.error} />;
|
if (app.error?.code === 'LOAD_ERROR' || app.error?.code === 'APP_ERROR') {
|
||||||
}
|
return <AppError app={app} error={app.error} />;
|
||||||
return (
|
}
|
||||||
<ErrorBoundary
|
return (
|
||||||
FallbackComponent={(props) => <AppError app={app} error={app.error} {...props} />}
|
<ErrorBoundary
|
||||||
onError={handleErrors}
|
FallbackComponent={(props) => <AppError app={app} error={app.error} {...props} />}
|
||||||
>
|
onError={handleErrors}
|
||||||
<ApplicationContext.Provider value={app}>
|
>
|
||||||
{app.maintained && app.maintaining && app.renderComponent('AppMaintainingDialog', { app })}
|
<ApplicationContext.Provider value={app}>
|
||||||
{app.renderComponent('AppMain')}
|
{app.maintained && app.maintaining && app.renderComponent('AppMaintainingDialog', { app })}
|
||||||
</ApplicationContext.Provider>
|
{app.renderComponent('AppMain')}
|
||||||
</ErrorBoundary>
|
</ApplicationContext.Provider>
|
||||||
);
|
</ErrorBoundary>
|
||||||
});
|
);
|
||||||
|
},
|
||||||
|
{ displayName: 'AppComponent' },
|
||||||
|
);
|
||||||
|
@ -2,3 +2,4 @@ import { createContext } from 'react';
|
|||||||
import { Application } from './Application';
|
import { Application } from './Application';
|
||||||
|
|
||||||
export const ApplicationContext = createContext<Application>(null);
|
export const ApplicationContext = createContext<Application>(null);
|
||||||
|
ApplicationContext.displayName = 'ApplicationContext';
|
||||||
|
@ -13,113 +13,114 @@ import { SchemaInitializerOptions } from '../types';
|
|||||||
const defaultWrap = (s: ISchema) => s;
|
const defaultWrap = (s: ISchema) => s;
|
||||||
|
|
||||||
export function withInitializer<T>(C: ComponentType<T>) {
|
export function withInitializer<T>(C: ComponentType<T>) {
|
||||||
const WithInitializer = observer((props: SchemaInitializerOptions<T>) => {
|
const WithInitializer = observer(
|
||||||
const { designable, insertAdjacent } = useDesignable();
|
(props: SchemaInitializerOptions<T>) => {
|
||||||
const { isInSubTable } = useFlag() || {};
|
const { designable, insertAdjacent } = useDesignable();
|
||||||
const {
|
const { isInSubTable } = useFlag() || {};
|
||||||
insert,
|
const {
|
||||||
useInsert,
|
insert,
|
||||||
wrap = defaultWrap,
|
useInsert,
|
||||||
insertPosition = 'beforeEnd',
|
wrap = defaultWrap,
|
||||||
onSuccess,
|
insertPosition = 'beforeEnd',
|
||||||
designable: propsDesignable,
|
onSuccess,
|
||||||
popoverProps,
|
designable: propsDesignable,
|
||||||
children,
|
popoverProps,
|
||||||
popover = true,
|
children,
|
||||||
style,
|
popover = true,
|
||||||
componentProps,
|
|
||||||
} = props;
|
|
||||||
|
|
||||||
// 插入 schema 的能力
|
|
||||||
const insertCallback = useInsert ? useInsert() : insert;
|
|
||||||
const insertSchema = useCallback(
|
|
||||||
(schema) => {
|
|
||||||
if (insertCallback) {
|
|
||||||
insertCallback(wrap(schema, { isInSubTable }));
|
|
||||||
} else {
|
|
||||||
insertAdjacent(insertPosition, wrap(schema, { isInSubTable }), { onSuccess });
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[insertCallback, wrap, insertAdjacent, insertPosition, onSuccess],
|
|
||||||
);
|
|
||||||
|
|
||||||
const { wrapSSR, hashId, componentCls } = useSchemaInitializerStyles();
|
|
||||||
const [visible, setVisible] = useState(false);
|
|
||||||
const { token } = theme.useToken();
|
|
||||||
const dropdownMaxHeight = useNiceDropdownMaxHeight([visible]);
|
|
||||||
|
|
||||||
const cProps = useMemo(
|
|
||||||
() => ({
|
|
||||||
options: props,
|
|
||||||
style,
|
style,
|
||||||
...componentProps,
|
componentProps,
|
||||||
}),
|
} = props;
|
||||||
[componentProps, props, style],
|
|
||||||
);
|
|
||||||
|
|
||||||
// designable 为 false 时,不渲染
|
// 插入 schema 的能力
|
||||||
if (!designable && propsDesignable !== true) {
|
const insertCallback = useInsert ? useInsert() : insert;
|
||||||
return null;
|
const insertSchema = useCallback(
|
||||||
}
|
(schema) => {
|
||||||
|
if (insertCallback) {
|
||||||
|
insertCallback(wrap(schema, { isInSubTable }));
|
||||||
|
} else {
|
||||||
|
insertAdjacent(insertPosition, wrap(schema, { isInSubTable }), { onSuccess });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[insertCallback, wrap, insertAdjacent, insertPosition, onSuccess],
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
const { wrapSSR, hashId, componentCls } = useSchemaInitializerStyles();
|
||||||
<SchemaInitializerContext.Provider
|
const [visible, setVisible] = useState(false);
|
||||||
value={{
|
const { token } = theme.useToken();
|
||||||
visible,
|
const dropdownMaxHeight = useNiceDropdownMaxHeight([visible]);
|
||||||
setVisible,
|
|
||||||
insert: insertSchema,
|
const cProps = useMemo(
|
||||||
|
() => ({
|
||||||
options: props,
|
options: props,
|
||||||
}}
|
style,
|
||||||
>
|
...componentProps,
|
||||||
{popover === false ? (
|
}),
|
||||||
React.createElement(C, cProps)
|
[componentProps, props, style],
|
||||||
) : (
|
);
|
||||||
<Popover
|
|
||||||
placement={'bottomLeft'}
|
// designable 为 false 时,不渲染
|
||||||
{...popoverProps}
|
if (!designable && propsDesignable !== true) {
|
||||||
arrow={false}
|
return null;
|
||||||
overlayClassName={css`
|
}
|
||||||
.ant-popover-inner {
|
|
||||||
padding: ${`${token.paddingXXS}px 0`};
|
return (
|
||||||
.ant-menu-submenu-title {
|
<SchemaInitializerContext.Provider
|
||||||
margin-block: 0;
|
value={{
|
||||||
|
visible,
|
||||||
|
setVisible,
|
||||||
|
insert: insertSchema,
|
||||||
|
options: props,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{popover === false ? (
|
||||||
|
React.createElement(C, cProps)
|
||||||
|
) : (
|
||||||
|
<Popover
|
||||||
|
placement={'bottomLeft'}
|
||||||
|
{...popoverProps}
|
||||||
|
arrow={false}
|
||||||
|
overlayClassName={css`
|
||||||
|
.ant-popover-inner {
|
||||||
|
padding: ${`${token.paddingXXS}px 0`};
|
||||||
|
.ant-menu-submenu-title {
|
||||||
|
margin-block: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
`}
|
||||||
`}
|
open={visible}
|
||||||
open={visible}
|
onOpenChange={setVisible}
|
||||||
onOpenChange={setVisible}
|
content={wrapSSR(
|
||||||
content={wrapSSR(
|
<div
|
||||||
<div
|
className={`${componentCls} ${hashId}`}
|
||||||
className={`${componentCls} ${hashId}`}
|
style={{
|
||||||
style={{
|
maxHeight: dropdownMaxHeight,
|
||||||
maxHeight: dropdownMaxHeight,
|
overflowY: 'auto',
|
||||||
overflowY: 'auto',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<ConfigProvider
|
|
||||||
theme={{
|
|
||||||
components: {
|
|
||||||
Menu: {
|
|
||||||
itemHeight: token.marginXL,
|
|
||||||
borderRadius: token.borderRadiusSM,
|
|
||||||
itemBorderRadius: token.borderRadiusSM,
|
|
||||||
subMenuItemBorderRadius: token.borderRadiusSM,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{children}
|
<ConfigProvider
|
||||||
</ConfigProvider>
|
theme={{
|
||||||
</div>,
|
components: {
|
||||||
)}
|
Menu: {
|
||||||
>
|
itemHeight: token.marginXL,
|
||||||
{React.createElement(C, cProps)}
|
borderRadius: token.borderRadiusSM,
|
||||||
</Popover>
|
itemBorderRadius: token.borderRadiusSM,
|
||||||
)}
|
subMenuItemBorderRadius: token.borderRadiusSM,
|
||||||
</SchemaInitializerContext.Provider>
|
},
|
||||||
);
|
},
|
||||||
});
|
}}
|
||||||
|
>
|
||||||
WithInitializer.displayName = `WithInitializer(${C.displayName || C.name})`;
|
{children}
|
||||||
|
</ConfigProvider>
|
||||||
|
</div>,
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{React.createElement(C, cProps)}
|
||||||
|
</Popover>
|
||||||
|
)}
|
||||||
|
</SchemaInitializerContext.Provider>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
{ displayName: `WithInitializer(${C.displayName || C.name})` },
|
||||||
|
);
|
||||||
return WithInitializer;
|
return WithInitializer;
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ export * from './useAriaAttributeOfMenuItem';
|
|||||||
|
|
||||||
export function useSchemaInitializerMenuItems(items: any[], name?: string, onClick?: (args: any) => void) {
|
export function useSchemaInitializerMenuItems(items: any[], name?: string, onClick?: (args: any) => void) {
|
||||||
const getMenuItems = useGetSchemaInitializerMenuItems(onClick);
|
const getMenuItems = useGetSchemaInitializerMenuItems(onClick);
|
||||||
return getMenuItems(items, name);
|
return useMemo(() => getMenuItems(items, name), [getMenuItems, items, name]);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useGetSchemaInitializerMenuItems(onClick?: (args: any) => void) {
|
export function useGetSchemaInitializerMenuItems(onClick?: (args: any) => void) {
|
||||||
|
@ -13,3 +13,4 @@ export const SchemaSettingsIcon: FC<SchemaSettingOptions> = React.memo((props) =
|
|||||||
const style = useMemo(() => ({ cursor: 'pointer', fontSize: 12 }), []);
|
const style = useMemo(() => ({ cursor: 'pointer', fontSize: 12 }), []);
|
||||||
return <MenuOutlined role="button" style={style} aria-label={getAriaLabel('schema-settings', name)} />;
|
return <MenuOutlined role="button" style={style} aria-label={getAriaLabel('schema-settings', name)} />;
|
||||||
});
|
});
|
||||||
|
SchemaSettingsIcon.displayName = 'SchemaSettingsIcon';
|
||||||
|
@ -3,6 +3,7 @@ import React, { createContext, useContext } from 'react';
|
|||||||
import { useRequest } from '../api-client';
|
import { useRequest } from '../api-client';
|
||||||
|
|
||||||
export const AsyncDataContext = createContext<Result<any, any> & { state?: any; setState?: any }>(null);
|
export const AsyncDataContext = createContext<Result<any, any> & { state?: any; setState?: any }>(null);
|
||||||
|
AsyncDataContext.displayName = 'AsyncDataContext';
|
||||||
|
|
||||||
export interface AsyncDataProviderProps {
|
export interface AsyncDataProviderProps {
|
||||||
value?: any;
|
value?: any;
|
||||||
|
@ -35,7 +35,9 @@ import { useDataBlockSourceId } from './hooks/useDataBlockSourceId';
|
|||||||
* @deprecated
|
* @deprecated
|
||||||
*/
|
*/
|
||||||
export const BlockResourceContext = createContext(null);
|
export const BlockResourceContext = createContext(null);
|
||||||
|
BlockResourceContext.displayName = 'BlockResourceContext';
|
||||||
export const BlockAssociationContext = createContext(null);
|
export const BlockAssociationContext = createContext(null);
|
||||||
|
BlockAssociationContext.displayName = 'BlockAssociationContext';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated
|
* @deprecated
|
||||||
@ -50,6 +52,7 @@ export const BlockRequestContext_deprecated = createContext<{
|
|||||||
__parent?: any;
|
__parent?: any;
|
||||||
updateAssociationValues?: any[];
|
updateAssociationValues?: any[];
|
||||||
}>({});
|
}>({});
|
||||||
|
BlockRequestContext_deprecated.displayName = 'BlockRequestContext_deprecated';
|
||||||
|
|
||||||
export const useBlockResource = () => {
|
export const useBlockResource = () => {
|
||||||
const resource = useDataBlockResource();
|
const resource = useDataBlockResource();
|
||||||
@ -209,6 +212,7 @@ const BlockContext = createContext<{
|
|||||||
/** 用以区分区块的标识 */
|
/** 用以区分区块的标识 */
|
||||||
name: string;
|
name: string;
|
||||||
}>(null);
|
}>(null);
|
||||||
|
BlockContext.displayName = 'BlockContext';
|
||||||
|
|
||||||
export const useBlockContext = () => {
|
export const useBlockContext = () => {
|
||||||
return useContext(BlockContext);
|
return useContext(BlockContext);
|
||||||
|
@ -9,6 +9,7 @@ import { BlockProvider, useBlockRequestContext } from './BlockProvider';
|
|||||||
import { useParsedFilter } from './hooks';
|
import { useParsedFilter } from './hooks';
|
||||||
|
|
||||||
export const DetailsBlockContext = createContext<any>({});
|
export const DetailsBlockContext = createContext<any>({});
|
||||||
|
DetailsBlockContext.displayName = 'DetailsBlockContext';
|
||||||
|
|
||||||
const InternalDetailsBlockProvider = (props) => {
|
const InternalDetailsBlockProvider = (props) => {
|
||||||
const { action, readPretty } = props;
|
const { action, readPretty } = props;
|
||||||
|
@ -12,6 +12,7 @@ import { TemplateBlockProvider } from './TemplateBlockProvider';
|
|||||||
import { FormActiveFieldsProvider } from './hooks/useFormActiveFields';
|
import { FormActiveFieldsProvider } from './hooks/useFormActiveFields';
|
||||||
|
|
||||||
export const FormBlockContext = createContext<any>({});
|
export const FormBlockContext = createContext<any>({});
|
||||||
|
FormBlockContext.displayName = 'FormBlockContext';
|
||||||
|
|
||||||
const InternalFormBlockProvider = (props) => {
|
const InternalFormBlockProvider = (props) => {
|
||||||
const ctx = useFormBlockContext();
|
const ctx = useFormBlockContext();
|
||||||
|
@ -10,6 +10,7 @@ import { BlockProvider, useBlockRequestContext } from './BlockProvider';
|
|||||||
import { useFormBlockContext } from './FormBlockProvider';
|
import { useFormBlockContext } from './FormBlockProvider';
|
||||||
|
|
||||||
export const FormFieldContext = createContext<any>({});
|
export const FormFieldContext = createContext<any>({});
|
||||||
|
FormFieldContext.displayName = 'FormFieldContext';
|
||||||
|
|
||||||
const InternalFormFieldProvider = (props) => {
|
const InternalFormFieldProvider = (props) => {
|
||||||
const { action, readPretty, fieldName } = props;
|
const { action, readPretty, fieldName } = props;
|
||||||
@ -75,6 +76,7 @@ const InternalFormFieldProvider = (props) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const WithoutFormFieldResource = createContext(null);
|
export const WithoutFormFieldResource = createContext(null);
|
||||||
|
WithoutFormFieldResource.displayName = 'WithoutFormFieldResource';
|
||||||
|
|
||||||
export const FormFieldProvider = (props) => {
|
export const FormFieldProvider = (props) => {
|
||||||
return (
|
return (
|
||||||
|
@ -9,6 +9,8 @@ import { BlockProvider, RenderChildrenWithAssociationFilter, useBlockRequestCont
|
|||||||
import { findFilterTargets, useParsedFilter } from './hooks';
|
import { findFilterTargets, useParsedFilter } from './hooks';
|
||||||
|
|
||||||
export const TableBlockContext = createContext<any>({});
|
export const TableBlockContext = createContext<any>({});
|
||||||
|
TableBlockContext.displayName = 'TableBlockContext';
|
||||||
|
|
||||||
export function getIdsWithChildren(nodes) {
|
export function getIdsWithChildren(nodes) {
|
||||||
const ids = [];
|
const ids = [];
|
||||||
if (nodes) {
|
if (nodes) {
|
||||||
|
@ -7,6 +7,7 @@ import { useFormBlockContext } from './FormBlockProvider';
|
|||||||
import { useFormFieldContext } from './FormFieldProvider';
|
import { useFormFieldContext } from './FormFieldProvider';
|
||||||
|
|
||||||
export const TableFieldContext = createContext<any>({});
|
export const TableFieldContext = createContext<any>({});
|
||||||
|
TableFieldContext.displayName = 'TableFieldContext';
|
||||||
|
|
||||||
const InternalTableFieldProvider = (props) => {
|
const InternalTableFieldProvider = (props) => {
|
||||||
const { params = {}, showIndex, dragSort, fieldName } = props;
|
const { params = {}, showIndex, dragSort, fieldName } = props;
|
||||||
@ -122,6 +123,7 @@ export class TableFieldResource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const WithoutTableFieldResource = createContext(null);
|
export const WithoutTableFieldResource = createContext(null);
|
||||||
|
WithoutTableFieldResource.displayName = 'WithoutTableFieldResource';
|
||||||
|
|
||||||
export const TableFieldProvider = (props) => {
|
export const TableFieldProvider = (props) => {
|
||||||
return (
|
return (
|
||||||
|
@ -20,7 +20,9 @@ type Params = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const TableSelectorContext = createContext<any>({});
|
export const TableSelectorContext = createContext<any>({});
|
||||||
|
TableSelectorContext.displayName = 'TableSelectorContext';
|
||||||
const TableSelectorParamsContext = createContext<Params>({}); // 用于传递参数
|
const TableSelectorParamsContext = createContext<Params>({}); // 用于传递参数
|
||||||
|
TableSelectorParamsContext.displayName = 'TableSelectorParamsContext';
|
||||||
|
|
||||||
type TableSelectorProviderProps = {
|
type TableSelectorProviderProps = {
|
||||||
params: Record<string, any>;
|
params: Record<string, any>;
|
||||||
|
@ -5,6 +5,7 @@ const TemplateBlockContext = createContext<{
|
|||||||
templateFinshed?: boolean;
|
templateFinshed?: boolean;
|
||||||
onTemplateSuccess?: Function;
|
onTemplateSuccess?: Function;
|
||||||
}>({});
|
}>({});
|
||||||
|
TemplateBlockContext.displayName = 'TemplateBlockContext';
|
||||||
|
|
||||||
export const useTemplateBlockContext = () => {
|
export const useTemplateBlockContext = () => {
|
||||||
return useContext(TemplateBlockContext);
|
return useContext(TemplateBlockContext);
|
||||||
|
@ -12,6 +12,7 @@ const CollectionHistoryContext = createContext<CollectionHistoryContextValue>({
|
|||||||
historyCollections: [],
|
historyCollections: [],
|
||||||
refreshCH: () => undefined,
|
refreshCH: () => undefined,
|
||||||
});
|
});
|
||||||
|
CollectionHistoryContext.displayName = 'CollectionHistoryContext';
|
||||||
|
|
||||||
export const CollectionHistoryProvider: React.FC = (props) => {
|
export const CollectionHistoryProvider: React.FC = (props) => {
|
||||||
const api = useAPIClient();
|
const api = useAPIClient();
|
||||||
|
@ -51,6 +51,4 @@ const Summary = observer(
|
|||||||
{ displayName: 'Summary' },
|
{ displayName: 'Summary' },
|
||||||
);
|
);
|
||||||
|
|
||||||
Summary.displayName = 'Summary';
|
|
||||||
|
|
||||||
export default Summary;
|
export default Summary;
|
||||||
|
@ -8,6 +8,7 @@ import { useAPIClient, useRequest } from '../api-client';
|
|||||||
export const ResourceActionContext = createContext<
|
export const ResourceActionContext = createContext<
|
||||||
Result<any, any> & { state?: any; setState?: any; dragSort?: boolean; defaultRequest?: any }
|
Result<any, any> & { state?: any; setState?: any; dragSort?: boolean; defaultRequest?: any }
|
||||||
>(null);
|
>(null);
|
||||||
|
ResourceActionContext.displayName = 'ResourceActionContext';
|
||||||
|
|
||||||
interface ResourceActionProviderProps {
|
interface ResourceActionProviderProps {
|
||||||
type?: 'association' | 'collection';
|
type?: 'association' | 'collection';
|
||||||
@ -18,6 +19,7 @@ interface ResourceActionProviderProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const ResourceContext = createContext<any>(null);
|
const ResourceContext = createContext<any>(null);
|
||||||
|
ResourceContext.displayName = 'ResourceContext';
|
||||||
|
|
||||||
const CollectionResourceActionProvider = (props) => {
|
const CollectionResourceActionProvider = (props) => {
|
||||||
const { collection, request, uid, dragSort } = props;
|
const { collection, request, uid, dragSort } = props;
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
import { createContext } from 'react';
|
import { createContext } from 'react';
|
||||||
|
|
||||||
export const CollectionCategroriesContext = createContext({ data: [], refresh: () => {} });
|
export const CollectionCategroriesContext = createContext({ data: [], refresh: () => {} });
|
||||||
|
CollectionCategroriesContext.displayName = 'CollectionCategroriesContext';
|
||||||
|
@ -69,6 +69,7 @@ const collection: CollectionOptions = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const DataSourceContext_deprecated = createContext(null);
|
export const DataSourceContext_deprecated = createContext(null);
|
||||||
|
DataSourceContext_deprecated.displayName = 'DataSourceContext_deprecated';
|
||||||
|
|
||||||
const useSelectedRowKeys = () => {
|
const useSelectedRowKeys = () => {
|
||||||
const ctx = useContext(DataSourceContext_deprecated);
|
const ctx = useContext(DataSourceContext_deprecated);
|
||||||
|
@ -100,115 +100,118 @@ const getDefaultCollectionFields = (presetFields, values) => {
|
|||||||
// 其他
|
// 其他
|
||||||
return defaults;
|
return defaults;
|
||||||
};
|
};
|
||||||
export const PresetFields = observer((props: any) => {
|
export const PresetFields = observer(
|
||||||
const { getInterface } = useCollectionManager_deprecated();
|
(props: any) => {
|
||||||
const form = useForm();
|
const { getInterface } = useCollectionManager_deprecated();
|
||||||
const compile = useCompile();
|
const form = useForm();
|
||||||
const [selectedRowKeys, setSelectedRowKeys] = useState([]);
|
const compile = useCompile();
|
||||||
const { t } = useTranslation();
|
const [selectedRowKeys, setSelectedRowKeys] = useState([]);
|
||||||
const column = [
|
const { t } = useTranslation();
|
||||||
{
|
const column = [
|
||||||
title: t('Field'),
|
{
|
||||||
dataIndex: 'field',
|
title: t('Field'),
|
||||||
key: 'field',
|
dataIndex: 'field',
|
||||||
},
|
key: 'field',
|
||||||
{
|
},
|
||||||
title: t('Interface'),
|
{
|
||||||
dataIndex: 'interface',
|
title: t('Interface'),
|
||||||
key: 'interface',
|
dataIndex: 'interface',
|
||||||
render: (value) => <Tag>{compile(getInterface(value)?.title)}</Tag>,
|
key: 'interface',
|
||||||
},
|
render: (value) => <Tag>{compile(getInterface(value)?.title)}</Tag>,
|
||||||
{
|
},
|
||||||
title: t('Description'),
|
{
|
||||||
dataIndex: 'description',
|
title: t('Description'),
|
||||||
key: 'description',
|
dataIndex: 'description',
|
||||||
},
|
key: 'description',
|
||||||
];
|
},
|
||||||
const dataSource = [
|
];
|
||||||
{
|
const dataSource = [
|
||||||
field: t('ID'),
|
{
|
||||||
interface: 'integer',
|
field: t('ID'),
|
||||||
description: t('Primary key, unique identifier, self growth'),
|
interface: 'integer',
|
||||||
name: 'id',
|
description: t('Primary key, unique identifier, self growth'),
|
||||||
},
|
name: 'id',
|
||||||
{
|
},
|
||||||
field: t('Created at'),
|
{
|
||||||
interface: 'createdAt',
|
field: t('Created at'),
|
||||||
description: t('Store the creation time of each record'),
|
interface: 'createdAt',
|
||||||
name: 'createdAt',
|
description: t('Store the creation time of each record'),
|
||||||
},
|
name: 'createdAt',
|
||||||
{
|
},
|
||||||
field: t('Last updated at'),
|
{
|
||||||
interface: 'updatedAt',
|
field: t('Last updated at'),
|
||||||
description: t('Store the last update time of each record'),
|
interface: 'updatedAt',
|
||||||
name: 'updatedAt',
|
description: t('Store the last update time of each record'),
|
||||||
},
|
name: 'updatedAt',
|
||||||
{
|
},
|
||||||
field: t('Created by'),
|
{
|
||||||
interface: 'createdBy',
|
field: t('Created by'),
|
||||||
description: t('Store the creation user of each record'),
|
interface: 'createdBy',
|
||||||
name: 'createdBy',
|
description: t('Store the creation user of each record'),
|
||||||
},
|
name: 'createdBy',
|
||||||
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
field: t('Last updated by'),
|
field: t('Last updated by'),
|
||||||
interface: 'updatedBy',
|
interface: 'updatedBy',
|
||||||
description: t('Store the last update user of each record'),
|
description: t('Store the last update user of each record'),
|
||||||
name: 'updatedBy',
|
name: 'updatedBy',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const config = {
|
const config = {
|
||||||
autoGenId: true,
|
autoGenId: true,
|
||||||
createdAt: true,
|
createdAt: true,
|
||||||
createdBy: true,
|
createdBy: true,
|
||||||
updatedAt: true,
|
updatedAt: true,
|
||||||
updatedBy: true,
|
updatedBy: true,
|
||||||
};
|
};
|
||||||
const initialValue = ['id', 'createdAt', 'createdBy', 'updatedAt', 'updatedBy'];
|
const initialValue = ['id', 'createdAt', 'createdBy', 'updatedAt', 'updatedBy'];
|
||||||
setSelectedRowKeys(initialValue);
|
setSelectedRowKeys(initialValue);
|
||||||
form.setValues({ ...form.values, ...config });
|
form.setValues({ ...form.values, ...config });
|
||||||
}, []);
|
}, []);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fields = getDefaultCollectionFields(
|
const fields = getDefaultCollectionFields(
|
||||||
selectedRowKeys.map((v) => {
|
selectedRowKeys.map((v) => {
|
||||||
return {
|
return {
|
||||||
name: v,
|
name: v,
|
||||||
};
|
|
||||||
}),
|
|
||||||
form.values,
|
|
||||||
);
|
|
||||||
form.setValuesIn('fields', fields);
|
|
||||||
}, [selectedRowKeys]);
|
|
||||||
return (
|
|
||||||
<Table
|
|
||||||
size="small"
|
|
||||||
pagination={false}
|
|
||||||
rowKey="name"
|
|
||||||
bordered
|
|
||||||
scroll={{ x: 600 }}
|
|
||||||
dataSource={dataSource}
|
|
||||||
columns={column}
|
|
||||||
rowSelection={{
|
|
||||||
type: 'checkbox',
|
|
||||||
selectedRowKeys,
|
|
||||||
onChange: (_, selectedRows) => {
|
|
||||||
const fields = getDefaultCollectionFields(selectedRows, form.values);
|
|
||||||
const config = {
|
|
||||||
autoGenId: !!fields.find((v) => v.name === 'id'),
|
|
||||||
createdAt: !!fields.find((v) => v.name === 'createdAt'),
|
|
||||||
createdBy: !!fields.find((v) => v.name === 'createdBy'),
|
|
||||||
updatedAt: !!fields.find((v) => v.name === 'updatedAt'),
|
|
||||||
updatedBy: !!fields.find((v) => v.name === 'updatedBy'),
|
|
||||||
};
|
};
|
||||||
setSelectedRowKeys(
|
}),
|
||||||
fields?.map?.((v) => {
|
form.values,
|
||||||
return v.name;
|
);
|
||||||
}),
|
form.setValuesIn('fields', fields);
|
||||||
);
|
}, [selectedRowKeys]);
|
||||||
form.setValues({ ...form.values, fields, ...config });
|
return (
|
||||||
},
|
<Table
|
||||||
}}
|
size="small"
|
||||||
/>
|
pagination={false}
|
||||||
);
|
rowKey="name"
|
||||||
});
|
bordered
|
||||||
|
scroll={{ x: 600 }}
|
||||||
|
dataSource={dataSource}
|
||||||
|
columns={column}
|
||||||
|
rowSelection={{
|
||||||
|
type: 'checkbox',
|
||||||
|
selectedRowKeys,
|
||||||
|
onChange: (_, selectedRows) => {
|
||||||
|
const fields = getDefaultCollectionFields(selectedRows, form.values);
|
||||||
|
const config = {
|
||||||
|
autoGenId: !!fields.find((v) => v.name === 'id'),
|
||||||
|
createdAt: !!fields.find((v) => v.name === 'createdAt'),
|
||||||
|
createdBy: !!fields.find((v) => v.name === 'createdBy'),
|
||||||
|
updatedAt: !!fields.find((v) => v.name === 'updatedAt'),
|
||||||
|
updatedBy: !!fields.find((v) => v.name === 'updatedBy'),
|
||||||
|
};
|
||||||
|
setSelectedRowKeys(
|
||||||
|
fields?.map?.((v) => {
|
||||||
|
return v.name;
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
form.setValues({ ...form.values, fields, ...config });
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
{ displayName: 'PresetFields' },
|
||||||
|
);
|
||||||
|
@ -73,222 +73,225 @@ const useSourceFieldsOptions = () => {
|
|||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const FieldsConfigure = observer(() => {
|
export const FieldsConfigure = observer(
|
||||||
const { t } = useTranslation();
|
() => {
|
||||||
const [dataSource, setDataSource] = useState([]);
|
const { t } = useTranslation();
|
||||||
const { data: res, error, loading } = useAsyncData();
|
const [dataSource, setDataSource] = useState([]);
|
||||||
const { data, fields: sourceFields } = res || {};
|
const { data: res, error, loading } = useAsyncData();
|
||||||
const field: ArrayField = useField();
|
const { data, fields: sourceFields } = res || {};
|
||||||
const { data: curFields } = useContext(ResourceActionContext);
|
const field: ArrayField = useField();
|
||||||
const compile = useCompile();
|
const { data: curFields } = useContext(ResourceActionContext);
|
||||||
const { getInterface, getCollectionField } = useCollectionManager_deprecated();
|
const compile = useCompile();
|
||||||
const options = useFieldInterfaceOptions();
|
const { getInterface, getCollectionField } = useCollectionManager_deprecated();
|
||||||
|
const options = useFieldInterfaceOptions();
|
||||||
|
|
||||||
const interfaceOptions = useMemo(
|
const interfaceOptions = useMemo(
|
||||||
() =>
|
() =>
|
||||||
options
|
options
|
||||||
.filter((v) => !['relation'].includes(v.key))
|
.filter((v) => !['relation'].includes(v.key))
|
||||||
.map((options, index) => ({
|
.map((options, index) => ({
|
||||||
...options,
|
...options,
|
||||||
key: index,
|
key: index,
|
||||||
label: compile(options.label),
|
label: compile(options.label),
|
||||||
options: options.children.map((option) => ({
|
options: options.children.map((option) => ({
|
||||||
...option,
|
...option,
|
||||||
label: compile(option.label),
|
label: compile(option.label),
|
||||||
|
})),
|
||||||
})),
|
})),
|
||||||
})),
|
[compile],
|
||||||
[compile],
|
|
||||||
);
|
|
||||||
const sourceFieldsOptions = useSourceFieldsOptions();
|
|
||||||
|
|
||||||
const refGetInterface = useRef(getInterface);
|
|
||||||
useEffect(() => {
|
|
||||||
const fieldsMp = new Map();
|
|
||||||
if (!loading) {
|
|
||||||
if (data && data.length) {
|
|
||||||
Object.entries(data?.[0] || {}).forEach(([col, val]) => {
|
|
||||||
const sourceField = sourceFields[col];
|
|
||||||
const fieldInterface = inferInterface(col, val);
|
|
||||||
const defaultConfig = refGetInterface.current(fieldInterface)?.default;
|
|
||||||
const uiSchema = sourceField?.uiSchema || defaultConfig?.uiSchema || {};
|
|
||||||
fieldsMp.set(col, {
|
|
||||||
name: col,
|
|
||||||
interface: sourceField?.interface || fieldInterface,
|
|
||||||
type: sourceField?.type || defaultConfig?.type,
|
|
||||||
source: sourceField?.source,
|
|
||||||
uiSchema: {
|
|
||||||
title: col,
|
|
||||||
...uiSchema,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
Object.entries(sourceFields || {}).forEach(([col, val]: [string, any]) =>
|
|
||||||
fieldsMp.set(col, {
|
|
||||||
name: col,
|
|
||||||
...val,
|
|
||||||
uiSchema: {
|
|
||||||
title: col,
|
|
||||||
...(val?.uiSchema || {}),
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (field.value?.length) {
|
|
||||||
field.value.forEach((item) => {
|
|
||||||
if (fieldsMp.has(item.name)) {
|
|
||||||
fieldsMp.set(item.name, item);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// if (curFields?.data.length) {
|
|
||||||
// curFields.data.forEach((field: any) => {
|
|
||||||
// if (fieldsMp.has(field.name)) {
|
|
||||||
// fieldsMp.set(field.name, field);
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
const fields = Array.from(fieldsMp.values());
|
|
||||||
if (!fields.length) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setDataSource(fields);
|
|
||||||
field.setValue(fields);
|
|
||||||
}, [loading, data, field, sourceFields, curFields]);
|
|
||||||
|
|
||||||
if (loading) {
|
|
||||||
return <Spin />;
|
|
||||||
}
|
|
||||||
if (!data && !error) {
|
|
||||||
return <Alert showIcon message={t('Please use a valid SELECT or WITH AS statement')} />;
|
|
||||||
}
|
|
||||||
const err = error as any;
|
|
||||||
if (err) {
|
|
||||||
const errMsg =
|
|
||||||
err?.response?.data?.errors?.map?.((item: { message: string }) => item.message).join('\n') || err.message;
|
|
||||||
return <Alert showIcon message={`${t('SQL error: ')}${errMsg}`} type="error" />;
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleFieldChange = (record: any, index: number) => {
|
|
||||||
const fields = [...dataSource];
|
|
||||||
fields.splice(index, 1, record);
|
|
||||||
setDataSource(fields);
|
|
||||||
field.setValue(
|
|
||||||
fields.map((f) => ({
|
|
||||||
...f,
|
|
||||||
source: typeof f.source === 'string' ? f.source : f.source?.filter?.(Boolean)?.join('.') || null,
|
|
||||||
})),
|
|
||||||
);
|
);
|
||||||
};
|
const sourceFieldsOptions = useSourceFieldsOptions();
|
||||||
|
|
||||||
const columns = [
|
const refGetInterface = useRef(getInterface);
|
||||||
{
|
useEffect(() => {
|
||||||
title: t('Field name'),
|
const fieldsMp = new Map();
|
||||||
dataIndex: 'name',
|
if (!loading) {
|
||||||
key: 'name',
|
if (data && data.length) {
|
||||||
width: 130,
|
Object.entries(data?.[0] || {}).forEach(([col, val]) => {
|
||||||
},
|
const sourceField = sourceFields[col];
|
||||||
{
|
const fieldInterface = inferInterface(col, val);
|
||||||
title: t('Field source'),
|
const defaultConfig = refGetInterface.current(fieldInterface)?.default;
|
||||||
dataIndex: 'source',
|
const uiSchema = sourceField?.uiSchema || defaultConfig?.uiSchema || {};
|
||||||
key: 'source',
|
fieldsMp.set(col, {
|
||||||
width: 200,
|
name: col,
|
||||||
render: (text: string, record: any, index: number) => {
|
interface: sourceField?.interface || fieldInterface,
|
||||||
const field = dataSource[index];
|
type: sourceField?.type || defaultConfig?.type,
|
||||||
return (
|
source: sourceField?.source,
|
||||||
<Cascader
|
uiSchema: {
|
||||||
defaultValue={typeof text === 'string' ? text?.split('.') : text}
|
title: col,
|
||||||
allowClear
|
...uiSchema,
|
||||||
options={compile(sourceFieldsOptions)}
|
},
|
||||||
placeholder={t('Select field source')}
|
});
|
||||||
onChange={(value: string[]) => {
|
});
|
||||||
let sourceField = sourceFields[value?.[1]];
|
} else {
|
||||||
if (!sourceField) {
|
Object.entries(sourceFields || {}).forEach(([col, val]: [string, any]) =>
|
||||||
sourceField = getCollectionField(value?.join('.') || '');
|
fieldsMp.set(col, {
|
||||||
}
|
name: col,
|
||||||
handleFieldChange(
|
...val,
|
||||||
{
|
uiSchema: {
|
||||||
...field,
|
title: col,
|
||||||
source: value,
|
...(val?.uiSchema || {}),
|
||||||
interface: sourceField?.interface,
|
},
|
||||||
type: sourceField?.type,
|
}),
|
||||||
uiSchema: sourceField?.uiSchema,
|
);
|
||||||
},
|
}
|
||||||
index,
|
}
|
||||||
);
|
|
||||||
}}
|
if (field.value?.length) {
|
||||||
/>
|
field.value.forEach((item) => {
|
||||||
);
|
if (fieldsMp.has(item.name)) {
|
||||||
|
fieldsMp.set(item.name, item);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (curFields?.data.length) {
|
||||||
|
// curFields.data.forEach((field: any) => {
|
||||||
|
// if (fieldsMp.has(field.name)) {
|
||||||
|
// fieldsMp.set(field.name, field);
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
|
const fields = Array.from(fieldsMp.values());
|
||||||
|
if (!fields.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setDataSource(fields);
|
||||||
|
field.setValue(fields);
|
||||||
|
}, [loading, data, field, sourceFields, curFields]);
|
||||||
|
|
||||||
|
if (loading) {
|
||||||
|
return <Spin />;
|
||||||
|
}
|
||||||
|
if (!data && !error) {
|
||||||
|
return <Alert showIcon message={t('Please use a valid SELECT or WITH AS statement')} />;
|
||||||
|
}
|
||||||
|
const err = error as any;
|
||||||
|
if (err) {
|
||||||
|
const errMsg =
|
||||||
|
err?.response?.data?.errors?.map?.((item: { message: string }) => item.message).join('\n') || err.message;
|
||||||
|
return <Alert showIcon message={`${t('SQL error: ')}${errMsg}`} type="error" />;
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleFieldChange = (record: any, index: number) => {
|
||||||
|
const fields = [...dataSource];
|
||||||
|
fields.splice(index, 1, record);
|
||||||
|
setDataSource(fields);
|
||||||
|
field.setValue(
|
||||||
|
fields.map((f) => ({
|
||||||
|
...f,
|
||||||
|
source: typeof f.source === 'string' ? f.source : f.source?.filter?.(Boolean)?.join('.') || null,
|
||||||
|
})),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
{
|
||||||
|
title: t('Field name'),
|
||||||
|
dataIndex: 'name',
|
||||||
|
key: 'name',
|
||||||
|
width: 130,
|
||||||
},
|
},
|
||||||
},
|
{
|
||||||
{
|
title: t('Field source'),
|
||||||
title: t('Field interface'),
|
dataIndex: 'source',
|
||||||
dataIndex: 'interface',
|
key: 'source',
|
||||||
key: 'interface',
|
width: 200,
|
||||||
width: 150,
|
render: (text: string, record: any, index: number) => {
|
||||||
render: (text: string, record: any, index: number) => {
|
const field = dataSource[index];
|
||||||
const field = dataSource[index];
|
return (
|
||||||
return field.source ? (
|
<Cascader
|
||||||
<Tag>{compile(getInterface(text)?.title) || text}</Tag>
|
defaultValue={typeof text === 'string' ? text?.split('.') : text}
|
||||||
) : (
|
allowClear
|
||||||
<Select
|
options={compile(sourceFieldsOptions)}
|
||||||
defaultValue={field.interface || 'input'}
|
placeholder={t('Select field source')}
|
||||||
style={{ width: '100%' }}
|
onChange={(value: string[]) => {
|
||||||
popupMatchSelectWidth={false}
|
let sourceField = sourceFields[value?.[1]];
|
||||||
onChange={(value) => {
|
if (!sourceField) {
|
||||||
const interfaceConfig = getInterface(value);
|
sourceField = getCollectionField(value?.join('.') || '');
|
||||||
handleFieldChange(
|
}
|
||||||
{
|
handleFieldChange(
|
||||||
...field,
|
{
|
||||||
interface: value || null,
|
...field,
|
||||||
uiSchema: {
|
source: value,
|
||||||
...interfaceConfig?.default?.uiSchema,
|
interface: sourceField?.interface,
|
||||||
title: interfaceConfig?.default?.uiSchema?.title || field.uiSchema?.title,
|
type: sourceField?.type,
|
||||||
|
uiSchema: sourceField?.uiSchema,
|
||||||
},
|
},
|
||||||
type: interfaceConfig?.default?.type,
|
index,
|
||||||
},
|
);
|
||||||
index,
|
}}
|
||||||
);
|
/>
|
||||||
}}
|
);
|
||||||
allowClear={true}
|
},
|
||||||
options={interfaceOptions}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
},
|
{
|
||||||
{
|
title: t('Field interface'),
|
||||||
title: t('Field display name'),
|
dataIndex: 'interface',
|
||||||
dataIndex: 'title',
|
key: 'interface',
|
||||||
key: 'title',
|
width: 150,
|
||||||
width: 180,
|
render: (text: string, record: any, index: number) => {
|
||||||
render: (text: string, record: any, index: number) => {
|
const field = dataSource[index];
|
||||||
const field = dataSource[index];
|
return field.source ? (
|
||||||
return (
|
<Tag>{compile(getInterface(text)?.title) || text}</Tag>
|
||||||
<Input
|
) : (
|
||||||
value={field.uiSchema?.title || text}
|
<Select
|
||||||
defaultValue={field.uiSchema?.title !== undefined ? field.uiSchema.title : field?.name}
|
defaultValue={field.interface || 'input'}
|
||||||
onChange={(e) =>
|
style={{ width: '100%' }}
|
||||||
handleFieldChange({ ...field, uiSchema: { ...field?.uiSchema, title: e.target.value } }, index)
|
popupMatchSelectWidth={false}
|
||||||
}
|
onChange={(value) => {
|
||||||
/>
|
const interfaceConfig = getInterface(value);
|
||||||
);
|
handleFieldChange(
|
||||||
|
{
|
||||||
|
...field,
|
||||||
|
interface: value || null,
|
||||||
|
uiSchema: {
|
||||||
|
...interfaceConfig?.default?.uiSchema,
|
||||||
|
title: interfaceConfig?.default?.uiSchema?.title || field.uiSchema?.title,
|
||||||
|
},
|
||||||
|
type: interfaceConfig?.default?.type,
|
||||||
|
},
|
||||||
|
index,
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
allowClear={true}
|
||||||
|
options={interfaceOptions}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
{
|
||||||
];
|
title: t('Field display name'),
|
||||||
return (
|
dataIndex: 'title',
|
||||||
<Table
|
key: 'title',
|
||||||
bordered
|
width: 180,
|
||||||
size="small"
|
render: (text: string, record: any, index: number) => {
|
||||||
columns={columns}
|
const field = dataSource[index];
|
||||||
dataSource={dataSource}
|
return (
|
||||||
scroll={{ y: 300 }}
|
<Input
|
||||||
pagination={false}
|
value={field.uiSchema?.title || text}
|
||||||
rowClassName="editable-row"
|
defaultValue={field.uiSchema?.title !== undefined ? field.uiSchema.title : field?.name}
|
||||||
rowKey="name"
|
onChange={(e) =>
|
||||||
/>
|
handleFieldChange({ ...field, uiSchema: { ...field?.uiSchema, title: e.target.value } }, index)
|
||||||
);
|
}
|
||||||
});
|
/>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
return (
|
||||||
|
<Table
|
||||||
|
bordered
|
||||||
|
size="small"
|
||||||
|
columns={columns}
|
||||||
|
dataSource={dataSource}
|
||||||
|
scroll={{ y: 300 }}
|
||||||
|
pagination={false}
|
||||||
|
rowClassName="editable-row"
|
||||||
|
rowKey="name"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
{ displayName: 'FieldsConfigure' },
|
||||||
|
);
|
||||||
|
@ -4,55 +4,58 @@ import { Table } from 'antd';
|
|||||||
import { Schema, observer, useForm } from '@formily/react';
|
import { Schema, observer, useForm } from '@formily/react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
export const PreviewTable = observer(() => {
|
export const PreviewTable = observer(
|
||||||
const { data: res, loading, error } = useAsyncData();
|
() => {
|
||||||
const { data } = res || {};
|
const { data: res, loading, error } = useAsyncData();
|
||||||
const { t } = useTranslation();
|
const { data } = res || {};
|
||||||
const form = useForm();
|
const { t } = useTranslation();
|
||||||
|
const form = useForm();
|
||||||
|
|
||||||
const fields = form.values.fields || [];
|
const fields = form.values.fields || [];
|
||||||
const titleMp = fields.reduce((mp: { [name: string]: string }, field: any) => {
|
const titleMp = fields.reduce((mp: { [name: string]: string }, field: any) => {
|
||||||
mp[field.name] = field?.uiSchema?.title;
|
mp[field.name] = field?.uiSchema?.title;
|
||||||
return mp;
|
return mp;
|
||||||
}, {});
|
}, {});
|
||||||
|
|
||||||
const columns = error
|
const columns = error
|
||||||
? []
|
? []
|
||||||
: Object.keys(data?.[0] || {}).map((col) => {
|
: Object.keys(data?.[0] || {}).map((col) => {
|
||||||
const title = titleMp[col];
|
const title = titleMp[col];
|
||||||
return {
|
return {
|
||||||
title: Schema.compile(title || col, { t }),
|
title: Schema.compile(title || col, { t }),
|
||||||
dataIndex: col,
|
dataIndex: col,
|
||||||
key: col,
|
key: col,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
const dataSource = error
|
const dataSource = error
|
||||||
? []
|
? []
|
||||||
: data?.map((record: any, index: number) => {
|
: data?.map((record: any, index: number) => {
|
||||||
const compiledRecord = Object.entries(record).reduce(
|
const compiledRecord = Object.entries(record).reduce(
|
||||||
(mp: { [key: string]: any }, [key, val]: [string, any]) => {
|
(mp: { [key: string]: any }, [key, val]: [string, any]) => {
|
||||||
if (typeof val !== 'string') {
|
if (typeof val !== 'string') {
|
||||||
mp[key] = val;
|
mp[key] = val;
|
||||||
|
return mp;
|
||||||
|
}
|
||||||
|
const compiled = Schema.compile(val, { t });
|
||||||
|
mp[key] = t(compiled);
|
||||||
return mp;
|
return mp;
|
||||||
}
|
},
|
||||||
const compiled = Schema.compile(val, { t });
|
{},
|
||||||
mp[key] = t(compiled);
|
);
|
||||||
return mp;
|
return { ...compiledRecord, key: index };
|
||||||
},
|
});
|
||||||
{},
|
|
||||||
);
|
|
||||||
return { ...compiledRecord, key: index };
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Table
|
<Table
|
||||||
bordered
|
bordered
|
||||||
dataSource={dataSource}
|
dataSource={dataSource}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
scroll={{ x: columns.length * 150, y: 300 }}
|
scroll={{ x: columns.length * 150, y: 300 }}
|
||||||
loading={loading}
|
loading={loading}
|
||||||
rowKey="key"
|
rowKey="key"
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
});
|
},
|
||||||
|
{ displayName: 'PreviewTable' },
|
||||||
|
);
|
||||||
|
@ -12,6 +12,7 @@ export interface AssociationProviderProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const ParentCollectionContext = createContext<Collection>(null);
|
const ParentCollectionContext = createContext<Collection>(null);
|
||||||
|
ParentCollectionContext.displayName = 'ParentCollectionContext';
|
||||||
|
|
||||||
const ParentCollectionProvider = (props) => {
|
const ParentCollectionProvider = (props) => {
|
||||||
const collection = useCollection();
|
const collection = useCollection();
|
||||||
|
@ -13,6 +13,7 @@ export const DocumentTitleContext = createContext<DocumentTitleContextProps>({
|
|||||||
title: null,
|
title: null,
|
||||||
setTitle() {},
|
setTitle() {},
|
||||||
});
|
});
|
||||||
|
DocumentTitleContext.displayName = 'DocumentTitleContext';
|
||||||
|
|
||||||
export const DocumentTitleProvider: React.FC<{ addonBefore?: string; addonAfter?: string }> = (props) => {
|
export const DocumentTitleProvider: React.FC<{ addonBefore?: string; addonAfter?: string }> = (props) => {
|
||||||
const { addonBefore, addonAfter } = props;
|
const { addonBefore, addonAfter } = props;
|
||||||
|
@ -58,6 +58,7 @@ interface FilterContextValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const FilterContext = createContext<FilterContextValue>(null);
|
const FilterContext = createContext<FilterContextValue>(null);
|
||||||
|
FilterContext.displayName = 'FilterContext';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 主要用于记录当前页面中的数据区块的信息,用于在过滤区块中使用
|
* 主要用于记录当前页面中的数据区块的信息,用于在过滤区块中使用
|
||||||
|
@ -15,6 +15,7 @@ const AppInner = memo(({ children }: { children: React.ReactNode }) => {
|
|||||||
|
|
||||||
return <>{children}</>;
|
return <>{children}</>;
|
||||||
});
|
});
|
||||||
|
AppInner.displayName = 'AppInner';
|
||||||
|
|
||||||
const AntdAppProvider = ({ children }: { children: React.ReactNode }) => {
|
const AntdAppProvider = ({ children }: { children: React.ReactNode }) => {
|
||||||
return (
|
return (
|
||||||
|
@ -25,6 +25,7 @@ interface GlobalThemeContextProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const GlobalThemeContext = createContext<GlobalThemeContextProps>(null);
|
const GlobalThemeContext = createContext<GlobalThemeContextProps>(null);
|
||||||
|
GlobalThemeContext.displayName = 'GlobalThemeContext';
|
||||||
|
|
||||||
export const useGlobalTheme = () => {
|
export const useGlobalTheme = () => {
|
||||||
return React.useContext(GlobalThemeContext) || ({ theme: {}, isDarkTheme: false } as GlobalThemeContextProps);
|
return React.useContext(GlobalThemeContext) || ({ theme: {}, isDarkTheme: false } as GlobalThemeContextProps);
|
||||||
|
@ -10,7 +10,9 @@ type Item = MenuProps['items'][0] & {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const GetMenuItemContext = createContext<{ collectMenuItem?(item: Item): void; onChange?: () => void }>(null);
|
export const GetMenuItemContext = createContext<{ collectMenuItem?(item: Item): void; onChange?: () => void }>(null);
|
||||||
|
GetMenuItemContext.displayName = 'GetMenuItemContext';
|
||||||
export const GetMenuItemsContext = createContext<{ pushMenuItem?(item: Item): void }>(null);
|
export const GetMenuItemsContext = createContext<{ pushMenuItem?(item: Item): void }>(null);
|
||||||
|
GetMenuItemsContext.displayName = 'GetMenuItemsContext';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用于为 SchemaInitializer.Item 组件提供一些方法,比如收集菜单项数据
|
* 用于为 SchemaInitializer.Item 组件提供一些方法,比如收集菜单项数据
|
||||||
|
@ -65,30 +65,33 @@ const useErrorProps = (app: Application, error: any) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const AppError: FC<{ error: Error; app: Application }> = observer(({ app, error }) => {
|
const AppError: FC<{ error: Error; app: Application }> = observer(
|
||||||
const props = useErrorProps(app, error);
|
({ app, error }) => {
|
||||||
return (
|
const props = useErrorProps(app, error);
|
||||||
<div>
|
return (
|
||||||
<Result
|
<div>
|
||||||
className={css`
|
<Result
|
||||||
top: 50%;
|
className={css`
|
||||||
position: absolute;
|
top: 50%;
|
||||||
width: 100%;
|
position: absolute;
|
||||||
transform: translate(0, -50%);
|
width: 100%;
|
||||||
`}
|
transform: translate(0, -50%);
|
||||||
status="error"
|
`}
|
||||||
title={app.i18n.t('App error')}
|
status="error"
|
||||||
subTitle={app.i18n.t(error?.message)}
|
title={app.i18n.t('App error')}
|
||||||
extra={[
|
subTitle={app.i18n.t(error?.message)}
|
||||||
<Button type="primary" key="try" onClick={() => window.location.reload()}>
|
extra={[
|
||||||
{app.i18n.t('Try again')}
|
<Button type="primary" key="try" onClick={() => window.location.reload()}>
|
||||||
</Button>,
|
{app.i18n.t('Try again')}
|
||||||
]}
|
</Button>,
|
||||||
{...props}
|
]}
|
||||||
/>
|
{...props}
|
||||||
</div>
|
/>
|
||||||
);
|
</div>
|
||||||
});
|
);
|
||||||
|
},
|
||||||
|
{ displayName: 'AppError' },
|
||||||
|
);
|
||||||
|
|
||||||
const getProps = (app: Application) => {
|
const getProps = (app: Application) => {
|
||||||
if (app.ws.serverDown) {
|
if (app.ws.serverDown) {
|
||||||
@ -195,39 +198,45 @@ const getProps = (app: Application) => {
|
|||||||
return {};
|
return {};
|
||||||
};
|
};
|
||||||
|
|
||||||
const AppMaintaining: FC<{ app: Application; error: Error }> = observer(({ app }) => {
|
const AppMaintaining: FC<{ app: Application; error: Error }> = observer(
|
||||||
const { icon, status, title, subTitle } = getProps(app);
|
({ app }) => {
|
||||||
return (
|
const { icon, status, title, subTitle } = getProps(app);
|
||||||
<div>
|
return (
|
||||||
<Result
|
<div>
|
||||||
className={css`
|
<Result
|
||||||
top: 50%;
|
className={css`
|
||||||
position: absolute;
|
top: 50%;
|
||||||
width: 100%;
|
position: absolute;
|
||||||
transform: translate(0, -50%);
|
width: 100%;
|
||||||
`}
|
transform: translate(0, -50%);
|
||||||
icon={icon}
|
`}
|
||||||
status={status}
|
icon={icon}
|
||||||
title={app.i18n.t(title)}
|
status={status}
|
||||||
subTitle={app.i18n.t(subTitle)}
|
title={app.i18n.t(title)}
|
||||||
// extra={[
|
subTitle={app.i18n.t(subTitle)}
|
||||||
// <Button type="primary" key="try" onClick={() => window.location.reload()}>
|
// extra={[
|
||||||
// {app.i18n.t('Try again')}
|
// <Button type="primary" key="try" onClick={() => window.location.reload()}>
|
||||||
// </Button>,
|
// {app.i18n.t('Try again')}
|
||||||
// ]}
|
// </Button>,
|
||||||
/>
|
// ]}
|
||||||
</div>
|
/>
|
||||||
);
|
</div>
|
||||||
});
|
);
|
||||||
|
},
|
||||||
|
{ displayName: 'AppMaintaining' },
|
||||||
|
);
|
||||||
|
|
||||||
const AppMaintainingDialog: FC<{ app: Application; error: Error }> = observer(({ app }) => {
|
const AppMaintainingDialog: FC<{ app: Application; error: Error }> = observer(
|
||||||
const { icon, status, title, subTitle } = getProps(app);
|
({ app }) => {
|
||||||
return (
|
const { icon, status, title, subTitle } = getProps(app);
|
||||||
<Modal open={true} footer={null} closable={false}>
|
return (
|
||||||
<Result icon={icon} status={status} title={app.i18n.t(title)} subTitle={app.i18n.t(subTitle)} />
|
<Modal open={true} footer={null} closable={false}>
|
||||||
</Modal>
|
<Result icon={icon} status={status} title={app.i18n.t(title)} subTitle={app.i18n.t(subTitle)} />
|
||||||
);
|
</Modal>
|
||||||
});
|
);
|
||||||
|
},
|
||||||
|
{ displayName: 'AppMaintainingDialog' },
|
||||||
|
);
|
||||||
|
|
||||||
const AppNotFound = () => {
|
const AppNotFound = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
import { createContext } from 'react';
|
import { createContext } from 'react';
|
||||||
|
|
||||||
export const PinnedPluginListContext = createContext({ items: {} });
|
export const PinnedPluginListContext = createContext({ items: {} });
|
||||||
|
PinnedPluginListContext.displayName = 'PinnedPluginListContext';
|
||||||
|
@ -73,3 +73,4 @@ export const PluginDocument: React.FC<PluginDocumentProps> = memo((props) => {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
PluginDocument.displayName = 'PluginDocument';
|
||||||
|
@ -9,6 +9,7 @@ import { ADMIN_SETTINGS_PATH, PluginSettingsPageType, useApp } from '../applicat
|
|||||||
import { useCompile } from '../schema-component';
|
import { useCompile } from '../schema-component';
|
||||||
|
|
||||||
export const SettingsCenterContext = createContext<any>({});
|
export const SettingsCenterContext = createContext<any>({});
|
||||||
|
SettingsCenterContext.displayName = 'SettingsCenterContext';
|
||||||
|
|
||||||
function getMenuItems(list: PluginSettingsPageType[]) {
|
function getMenuItems(list: PluginSettingsPageType[]) {
|
||||||
return list.map((item) => {
|
return list.map((item) => {
|
||||||
|
@ -4,7 +4,9 @@ import { CollectionRecordProvider } from '../data-source';
|
|||||||
import { useCurrentUserContext } from '../user';
|
import { useCurrentUserContext } from '../user';
|
||||||
|
|
||||||
export const RecordContext_deprecated = createContext({});
|
export const RecordContext_deprecated = createContext({});
|
||||||
|
RecordContext_deprecated.displayName = 'RecordContext_deprecated';
|
||||||
export const RecordIndexContext = createContext(null);
|
export const RecordIndexContext = createContext(null);
|
||||||
|
RecordIndexContext.displayName = 'RecordIndexContext';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated use `CollectionRecordProvider` instead
|
* @deprecated use `CollectionRecordProvider` instead
|
||||||
|
@ -54,6 +54,7 @@ const filterByACL = (schema, options) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const SchemaIdContext = createContext(null);
|
const SchemaIdContext = createContext(null);
|
||||||
|
SchemaIdContext.displayName = 'SchemaIdContext';
|
||||||
const useMenuProps = () => {
|
const useMenuProps = () => {
|
||||||
const defaultSelectedUid = useContext(SchemaIdContext);
|
const defaultSelectedUid = useContext(SchemaIdContext);
|
||||||
return {
|
return {
|
||||||
|
@ -4,6 +4,7 @@ import React, { createContext } from 'react';
|
|||||||
import { useActionContext } from './hooks';
|
import { useActionContext } from './hooks';
|
||||||
|
|
||||||
export const ActionContext = createContext<ActionContextProps>({});
|
export const ActionContext = createContext<ActionContextProps>({});
|
||||||
|
ActionContext.displayName = 'ActionContext';
|
||||||
|
|
||||||
export const ActionContextProvider: React.FC<ActionContextProps & { value?: ActionContextProps }> = (props) => {
|
export const ActionContextProvider: React.FC<ActionContextProps & { value?: ActionContextProps }> = (props) => {
|
||||||
const contextProps = useActionContext();
|
const contextProps = useActionContext();
|
||||||
|
@ -40,116 +40,119 @@ export const filterAnalyses = (filters): any[] => {
|
|||||||
return results;
|
return results;
|
||||||
};
|
};
|
||||||
|
|
||||||
const InternalAssociationSelect = observer((props: AssociationSelectProps) => {
|
const InternalAssociationSelect = observer(
|
||||||
const { objectValue = true } = props;
|
(props: AssociationSelectProps) => {
|
||||||
const field: any = useField();
|
const { objectValue = true } = props;
|
||||||
const fieldSchema = useFieldSchema();
|
const field: any = useField();
|
||||||
const service = useServiceOptions(props);
|
const fieldSchema = useFieldSchema();
|
||||||
const { options: collectionField } = useAssociationFieldContext();
|
const service = useServiceOptions(props);
|
||||||
const initValue = isVariable(props.value) ? undefined : props.value;
|
const { options: collectionField } = useAssociationFieldContext();
|
||||||
const value = Array.isArray(initValue) ? initValue.filter(Boolean) : initValue;
|
const initValue = isVariable(props.value) ? undefined : props.value;
|
||||||
// 因为通过 Schema 的形式书写的组件,在值变更的时候 `value` 的值没有改变,所以需要维护一个 `innerValue` 来变更值
|
|
||||||
const [innerValue, setInnerValue] = useState(value);
|
|
||||||
const addMode = fieldSchema['x-component-props']?.addMode;
|
|
||||||
const isAllowAddNew = fieldSchema['x-add-new'];
|
|
||||||
const { t } = useTranslation();
|
|
||||||
const { multiple } = props;
|
|
||||||
const form = useForm();
|
|
||||||
const api = useAPIClient();
|
|
||||||
const resource = api.resource(collectionField.target);
|
|
||||||
const linkageFields = filterAnalyses(field.componentProps?.service?.params?.filter);
|
|
||||||
const recordData = useCollectionRecordData();
|
|
||||||
useEffect(() => {
|
|
||||||
const initValue = isVariable(field.value) ? undefined : field.value;
|
|
||||||
const value = Array.isArray(initValue) ? initValue.filter(Boolean) : initValue;
|
const value = Array.isArray(initValue) ? initValue.filter(Boolean) : initValue;
|
||||||
setInnerValue(value);
|
// 因为通过 Schema 的形式书写的组件,在值变更的时候 `value` 的值没有改变,所以需要维护一个 `innerValue` 来变更值
|
||||||
}, [field.value]);
|
const [innerValue, setInnerValue] = useState(value);
|
||||||
useEffect(() => {
|
const addMode = fieldSchema['x-component-props']?.addMode;
|
||||||
const id = uid();
|
const isAllowAddNew = fieldSchema['x-add-new'];
|
||||||
form.addEffects(id, () => {
|
const { t } = useTranslation();
|
||||||
if (linkageFields?.length > 0) {
|
const { multiple } = props;
|
||||||
//支持深层次子表单
|
const form = useForm();
|
||||||
onFieldChange('*', (fieldPath: any) => {
|
const api = useAPIClient();
|
||||||
if (linkageFields.includes(fieldPath.props.name) && field.value) {
|
const resource = api.resource(collectionField.target);
|
||||||
props.onChange(field.initialValue);
|
const linkageFields = filterAnalyses(field.componentProps?.service?.params?.filter);
|
||||||
setInnerValue(field.initialValue);
|
const recordData = useCollectionRecordData();
|
||||||
}
|
useEffect(() => {
|
||||||
});
|
const initValue = isVariable(field.value) ? undefined : field.value;
|
||||||
}
|
const value = Array.isArray(initValue) ? initValue.filter(Boolean) : initValue;
|
||||||
});
|
setInnerValue(value);
|
||||||
|
}, [field.value]);
|
||||||
|
useEffect(() => {
|
||||||
|
const id = uid();
|
||||||
|
form.addEffects(id, () => {
|
||||||
|
if (linkageFields?.length > 0) {
|
||||||
|
//支持深层次子表单
|
||||||
|
onFieldChange('*', (fieldPath: any) => {
|
||||||
|
if (linkageFields.includes(fieldPath.props.name) && field.value) {
|
||||||
|
props.onChange(field.initialValue);
|
||||||
|
setInnerValue(field.initialValue);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
form.removeEffects(id);
|
form.removeEffects(id);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleCreateAction = async (props) => {
|
||||||
|
const { search: value, callBack } = props;
|
||||||
|
const {
|
||||||
|
data: { data },
|
||||||
|
} = await resource.create({
|
||||||
|
values: {
|
||||||
|
[field?.componentProps?.fieldNames?.label || 'id']: value,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (data) {
|
||||||
|
if (['m2m', 'o2m'].includes(collectionField?.interface) && multiple !== false) {
|
||||||
|
const values = form.getValuesIn(field.path) || [];
|
||||||
|
values.push(data);
|
||||||
|
form.setValuesIn(field.path, values);
|
||||||
|
field.onInput(values);
|
||||||
|
} else {
|
||||||
|
form.setValuesIn(field.path, data);
|
||||||
|
field.onInput(data);
|
||||||
|
}
|
||||||
|
isFunction(callBack) && callBack?.();
|
||||||
|
message.success(t('Saved successfully'));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const QuickAddContent = (props) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
onClick={() => handleCreateAction(props)}
|
||||||
|
style={{ cursor: 'pointer', padding: '5px 12px', color: '#0d0c0c' }}
|
||||||
|
>
|
||||||
|
<PlusOutlined />
|
||||||
|
<span style={{ paddingLeft: 5 }}>{t('Add') + ` “${props.search}” `}</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
}, []);
|
|
||||||
|
|
||||||
const handleCreateAction = async (props) => {
|
|
||||||
const { search: value, callBack } = props;
|
|
||||||
const {
|
|
||||||
data: { data },
|
|
||||||
} = await resource.create({
|
|
||||||
values: {
|
|
||||||
[field?.componentProps?.fieldNames?.label || 'id']: value,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
if (data) {
|
|
||||||
if (['m2m', 'o2m'].includes(collectionField?.interface) && multiple !== false) {
|
|
||||||
const values = form.getValuesIn(field.path) || [];
|
|
||||||
values.push(data);
|
|
||||||
form.setValuesIn(field.path, values);
|
|
||||||
field.onInput(values);
|
|
||||||
} else {
|
|
||||||
form.setValuesIn(field.path, data);
|
|
||||||
field.onInput(data);
|
|
||||||
}
|
|
||||||
isFunction(callBack) && callBack?.();
|
|
||||||
message.success(t('Saved successfully'));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const QuickAddContent = (props) => {
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div key={fieldSchema.name}>
|
||||||
onClick={() => handleCreateAction(props)}
|
<Space.Compact style={{ display: 'flex', lineHeight: '32px' }}>
|
||||||
style={{ cursor: 'pointer', padding: '5px 12px', color: '#0d0c0c' }}
|
<RemoteSelect
|
||||||
>
|
style={{ width: '100%' }}
|
||||||
<PlusOutlined />
|
{...props}
|
||||||
<span style={{ paddingLeft: 5 }}>{t('Add') + ` “${props.search}” `}</span>
|
size={'middle'}
|
||||||
|
objectValue={objectValue}
|
||||||
|
value={value || innerValue}
|
||||||
|
service={service}
|
||||||
|
onChange={(value) => {
|
||||||
|
const val = value?.length !== 0 ? value : null;
|
||||||
|
props.onChange?.(val);
|
||||||
|
}}
|
||||||
|
CustomDropdownRender={addMode === 'quickAdd' && QuickAddContent}
|
||||||
|
></RemoteSelect>
|
||||||
|
|
||||||
|
{(addMode === 'modalAdd' || isAllowAddNew) && (
|
||||||
|
<RecordProvider isNew={true} record={null} parent={recordData}>
|
||||||
|
<RecursionField
|
||||||
|
onlyRenderProperties
|
||||||
|
basePath={field.address}
|
||||||
|
schema={fieldSchema}
|
||||||
|
filterProperties={(s) => {
|
||||||
|
return s['x-component'] === 'Action';
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</RecordProvider>
|
||||||
|
)}
|
||||||
|
</Space.Compact>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
},
|
||||||
return (
|
{ displayName: 'AssociationSelect' },
|
||||||
<div key={fieldSchema.name}>
|
);
|
||||||
<Space.Compact style={{ display: 'flex', lineHeight: '32px' }}>
|
|
||||||
<RemoteSelect
|
|
||||||
style={{ width: '100%' }}
|
|
||||||
{...props}
|
|
||||||
size={'middle'}
|
|
||||||
objectValue={objectValue}
|
|
||||||
value={value || innerValue}
|
|
||||||
service={service}
|
|
||||||
onChange={(value) => {
|
|
||||||
const val = value?.length !== 0 ? value : null;
|
|
||||||
props.onChange?.(val);
|
|
||||||
}}
|
|
||||||
CustomDropdownRender={addMode === 'quickAdd' && QuickAddContent}
|
|
||||||
></RemoteSelect>
|
|
||||||
|
|
||||||
{(addMode === 'modalAdd' || isAllowAddNew) && (
|
|
||||||
<RecordProvider isNew={true} record={null} parent={recordData}>
|
|
||||||
<RecursionField
|
|
||||||
onlyRenderProperties
|
|
||||||
basePath={field.address}
|
|
||||||
schema={fieldSchema}
|
|
||||||
filterProperties={(s) => {
|
|
||||||
return s['x-component'] === 'Action';
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</RecordProvider>
|
|
||||||
)}
|
|
||||||
</Space.Compact>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
interface AssociationSelectInterface {
|
interface AssociationSelectInterface {
|
||||||
(props: any): React.ReactElement;
|
(props: any): React.ReactElement;
|
||||||
|
@ -10,3 +10,4 @@ export interface AssociationFieldContextProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const AssociationFieldContext = createContext<AssociationFieldContextProps>({});
|
export const AssociationFieldContext = createContext<AssociationFieldContextProps>({});
|
||||||
|
AssociationFieldContext.displayName = 'AssociationFieldContext';
|
||||||
|
@ -179,6 +179,7 @@ export const useFieldNames = (props) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const SubFormContext = createContext<Record<string, any>>(null);
|
const SubFormContext = createContext<Record<string, any>>(null);
|
||||||
|
SubFormContext.displayName = 'SubFormContext';
|
||||||
export const SubFormProvider = SubFormContext.Provider;
|
export const SubFormProvider = SubFormContext.Provider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -12,6 +12,7 @@ import { Action } from '../action';
|
|||||||
import { StablePopover } from '../popover';
|
import { StablePopover } from '../popover';
|
||||||
|
|
||||||
export const FilterActionContext = createContext<any>(null);
|
export const FilterActionContext = createContext<any>(null);
|
||||||
|
FilterActionContext.displayName = 'FilterActionContext';
|
||||||
|
|
||||||
export const FilterAction = observer(
|
export const FilterAction = observer(
|
||||||
(props: any) => {
|
(props: any) => {
|
||||||
|
@ -12,5 +12,8 @@ export interface FilterContextProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const RemoveConditionContext = createContext(null);
|
export const RemoveConditionContext = createContext(null);
|
||||||
|
RemoveConditionContext.displayName = 'RemoveConditionContext';
|
||||||
export const FilterContext = createContext<FilterContextProps>(null);
|
export const FilterContext = createContext<FilterContextProps>(null);
|
||||||
|
FilterContext.displayName = 'FilterContext';
|
||||||
export const FilterLogicContext = createContext(null);
|
export const FilterLogicContext = createContext(null);
|
||||||
|
FilterLogicContext.displayName = 'FilterLogicContext';
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { useFieldSchema } from '@formily/react';
|
import { useFieldSchema } from '@formily/react';
|
||||||
import { useCollection_deprecated, useCollectionManager_deprecated } from '../../../collection-manager';
|
import { useCollection_deprecated, useCollectionManager_deprecated } from '../../../collection-manager';
|
||||||
|
import { useMemo } from 'react';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取当前字段所支持的操作符列表
|
* 获取当前字段所支持的操作符列表
|
||||||
@ -7,15 +8,17 @@ import { useCollection_deprecated, useCollectionManager_deprecated } from '../..
|
|||||||
*/
|
*/
|
||||||
export const useOperatorList = (): any[] => {
|
export const useOperatorList = (): any[] => {
|
||||||
const schema = useFieldSchema();
|
const schema = useFieldSchema();
|
||||||
const fieldInterface = schema['x-designer-props']?.interface;
|
|
||||||
const { name } = useCollection_deprecated();
|
const { name } = useCollection_deprecated();
|
||||||
const { getCollectionFields, getInterface } = useCollectionManager_deprecated();
|
const { getCollectionFields, getInterface } = useCollectionManager_deprecated();
|
||||||
const collectionFields = getCollectionFields(name);
|
|
||||||
|
|
||||||
if (fieldInterface) {
|
const res = useMemo(() => {
|
||||||
return getInterface(fieldInterface)?.filterable?.operators || [];
|
const fieldInterface = schema['x-designer-props']?.interface;
|
||||||
}
|
const collectionFields = getCollectionFields(name);
|
||||||
|
if (fieldInterface) {
|
||||||
const field = collectionFields.find((item) => item.name === schema.name);
|
return getInterface(fieldInterface)?.filterable?.operators || [];
|
||||||
return getInterface(field?.interface)?.filterable?.operators || [];
|
}
|
||||||
|
const field = collectionFields.find((item) => item.name === schema.name);
|
||||||
|
return getInterface(field?.interface)?.filterable?.operators || [];
|
||||||
|
}, [schema.name]);
|
||||||
|
return res;
|
||||||
};
|
};
|
||||||
|
@ -78,9 +78,12 @@ export function FormDialog(title: any, id: any, renderer?: any, theme?: any): IF
|
|||||||
root.unmount();
|
root.unmount();
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const DialogContent = observer(() => {
|
const DialogContent = observer(
|
||||||
return <Fragment>{isFn(renderer) ? renderer(env.form) : renderer}</Fragment>;
|
() => {
|
||||||
});
|
return <Fragment>{isFn(renderer) ? renderer(env.form) : renderer}</Fragment>;
|
||||||
|
},
|
||||||
|
{ displayName: 'DialogContent' },
|
||||||
|
);
|
||||||
const renderDialog = (open = true, resolve?: () => any, reject?: () => any) => {
|
const renderDialog = (open = true, resolve?: () => any, reject?: () => any) => {
|
||||||
const { form } = env;
|
const { form } = env;
|
||||||
if (!form) return null;
|
if (!form) return null;
|
||||||
|
@ -87,6 +87,7 @@ const useDefaultValues = (opts: any = {}, props: FormProps = {}) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const FormBlockContext = createContext<any>(null);
|
const FormBlockContext = createContext<any>(null);
|
||||||
|
FormBlockContext.displayName = 'FormBlockContext';
|
||||||
|
|
||||||
export const Form: React.FC<FormProps> & { Designer?: any } = observer(
|
export const Form: React.FC<FormProps> & { Designer?: any } = observer(
|
||||||
(props) => {
|
(props) => {
|
||||||
|
@ -126,6 +126,7 @@ export const G2PlotRenderer = forwardRef(function <O = any>(props: ReactG2PlotPr
|
|||||||
|
|
||||||
return <div className={cls(['g2plot', className])} ref={containerRef} />;
|
return <div className={cls(['g2plot', className])} ref={containerRef} />;
|
||||||
});
|
});
|
||||||
|
G2PlotRenderer.displayName = 'G2PlotRenderer';
|
||||||
|
|
||||||
export const G2Plot: any = observer(
|
export const G2Plot: any = observer(
|
||||||
(props: any) => {
|
(props: any) => {
|
||||||
@ -140,12 +141,14 @@ export const G2Plot: any = observer(
|
|||||||
if (typeof fn === 'function') {
|
if (typeof fn === 'function') {
|
||||||
const result = fn.bind({ api })();
|
const result = fn.bind({ api })();
|
||||||
if (result?.then) {
|
if (result?.then) {
|
||||||
result.then((data) => {
|
result
|
||||||
if (Array.isArray(data)) {
|
.then((data) => {
|
||||||
field.componentProps.config.data = data;
|
if (Array.isArray(data)) {
|
||||||
}
|
field.componentProps.config.data = data;
|
||||||
field.data.loading = false;
|
}
|
||||||
});
|
field.data.loading = false;
|
||||||
|
})
|
||||||
|
.catch(console.error);
|
||||||
} else {
|
} else {
|
||||||
field.data.loading = false;
|
field.data.loading = false;
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import React, { createContext, useContext, useEffect, useMemo } from 'react';
|
|||||||
import { BlockProvider, useBlockRequestContext, useParsedFilter } from '../../../block-provider';
|
import { BlockProvider, useBlockRequestContext, useParsedFilter } from '../../../block-provider';
|
||||||
import useStyles from './GridCard.Decorator.style';
|
import useStyles from './GridCard.Decorator.style';
|
||||||
export const GridCardBlockContext = createContext<any>({});
|
export const GridCardBlockContext = createContext<any>({});
|
||||||
|
GridCardBlockContext.displayName = 'GridCardBlockContext';
|
||||||
|
|
||||||
const InternalGridCardBlockProvider = (props) => {
|
const InternalGridCardBlockProvider = (props) => {
|
||||||
const { resource, service } = useBlockRequestContext();
|
const { resource, service } = useBlockRequestContext();
|
||||||
|
@ -11,8 +11,11 @@ import { useToken } from '../__builtins__';
|
|||||||
import useStyles from './Grid.style';
|
import useStyles from './Grid.style';
|
||||||
|
|
||||||
const GridRowContext = createContext<any>({});
|
const GridRowContext = createContext<any>({});
|
||||||
|
GridRowContext.displayName = 'GridRowContext';
|
||||||
const GridColContext = createContext<any>({});
|
const GridColContext = createContext<any>({});
|
||||||
|
GridColContext.displayName = 'GridColContext';
|
||||||
const GridContext = createContext<any>({});
|
const GridContext = createContext<any>({});
|
||||||
|
GridContext.displayName = 'GridContext';
|
||||||
|
|
||||||
const breakRemoveOnGrid = (s: Schema) => s['x-component'] === 'Grid';
|
const breakRemoveOnGrid = (s: Schema) => s['x-component'] === 'Grid';
|
||||||
const breakRemoveOnRow = (s: Schema) => s['x-component'] === 'Grid.Row';
|
const breakRemoveOnRow = (s: Schema) => s['x-component'] === 'Grid.Row';
|
||||||
|
@ -77,3 +77,4 @@ export const EllipsisWithTooltip = forwardRef((props: Partial<IEllipsisWithToolt
|
|||||||
</Popover>
|
</Popover>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
EllipsisWithTooltip.displayName = 'EllipsisWithTooltip';
|
||||||
|
@ -67,3 +67,4 @@ export const Json = React.forwardRef<typeof Input.TextArea, JSONTextAreaProps>(
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
Json.displayName = 'Json';
|
||||||
|
@ -7,6 +7,7 @@ import React, { createContext, useContext, useEffect, useMemo } from 'react';
|
|||||||
import { BlockProvider, useBlockRequestContext, useParsedFilter } from '../../../block-provider';
|
import { BlockProvider, useBlockRequestContext, useParsedFilter } from '../../../block-provider';
|
||||||
|
|
||||||
export const ListBlockContext = createContext<any>({});
|
export const ListBlockContext = createContext<any>({});
|
||||||
|
ListBlockContext.displayName = 'ListBlockContext';
|
||||||
|
|
||||||
const InternalListBlockProvider = (props) => {
|
const InternalListBlockProvider = (props) => {
|
||||||
const { resource, service } = useBlockRequestContext();
|
const { resource, service } = useBlockRequestContext();
|
||||||
|
@ -350,7 +350,6 @@ const SideMenu = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const MenuModeContext = createContext(null);
|
const MenuModeContext = createContext(null);
|
||||||
|
|
||||||
MenuModeContext.displayName = 'MenuModeContext';
|
MenuModeContext.displayName = 'MenuModeContext';
|
||||||
|
|
||||||
const useSideMenuRef = () => {
|
const useSideMenuRef = () => {
|
||||||
|
@ -6,74 +6,80 @@ import React, { useMemo, useRef } from 'react';
|
|||||||
import { useCollectionManager_deprecated } from '../../../collection-manager';
|
import { useCollectionManager_deprecated } from '../../../collection-manager';
|
||||||
import { StablePopover } from '../popover';
|
import { StablePopover } from '../popover';
|
||||||
|
|
||||||
export const Editable = observer((props) => {
|
export const Editable = observer(
|
||||||
const field: any = useField();
|
(props) => {
|
||||||
const containerRef = useRef(null);
|
const field: any = useField();
|
||||||
const fieldSchema = useFieldSchema();
|
const containerRef = useRef(null);
|
||||||
const value = field.value;
|
const fieldSchema = useFieldSchema();
|
||||||
const schema: any = {
|
const value = field.value;
|
||||||
name: fieldSchema.name,
|
const schema: any = {
|
||||||
'x-collection-field': fieldSchema['x-collection-field'],
|
name: fieldSchema.name,
|
||||||
'x-component': 'CollectionField',
|
'x-collection-field': fieldSchema['x-collection-field'],
|
||||||
'x-read-pretty': true,
|
'x-component': 'CollectionField',
|
||||||
default: value,
|
'x-read-pretty': true,
|
||||||
'x-component-props': fieldSchema['x-component-props'],
|
default: value,
|
||||||
};
|
'x-component-props': fieldSchema['x-component-props'],
|
||||||
const form = useMemo(
|
};
|
||||||
() =>
|
const form = useMemo(
|
||||||
createForm({
|
() =>
|
||||||
values: {
|
createForm({
|
||||||
[fieldSchema.name]: value,
|
values: {
|
||||||
},
|
[fieldSchema.name]: value,
|
||||||
}),
|
},
|
||||||
[field.value, fieldSchema['x-component-props']],
|
}),
|
||||||
);
|
[field.value, fieldSchema['x-component-props']],
|
||||||
const getContainer = () => {
|
);
|
||||||
return containerRef.current;
|
const getContainer = () => {
|
||||||
};
|
return containerRef.current;
|
||||||
|
};
|
||||||
|
|
||||||
const modifiedChildren = React.Children.map(props.children, (child) => {
|
const modifiedChildren = React.Children.map(props.children, (child) => {
|
||||||
if (React.isValidElement(child)) {
|
if (React.isValidElement(child)) {
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
return React.cloneElement(child, { getContainer });
|
return React.cloneElement(child, { getContainer });
|
||||||
}
|
}
|
||||||
return child;
|
return child;
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FormItem {...props} labelStyle={{ display: 'none' }}>
|
<FormItem {...props} labelStyle={{ display: 'none' }}>
|
||||||
<StablePopover
|
<StablePopover
|
||||||
content={
|
content={
|
||||||
<div style={{ width: '100%', height: '100%', minWidth: 500 }}>
|
<div style={{ width: '100%', height: '100%', minWidth: 500 }}>
|
||||||
<div ref={containerRef}>{modifiedChildren}</div>
|
<div ref={containerRef}>{modifiedChildren}</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
|
||||||
trigger="click"
|
|
||||||
placement={'bottomLeft'}
|
|
||||||
overlayClassName={css`
|
|
||||||
padding-top: 0;
|
|
||||||
.ant-popover-arrow {
|
|
||||||
display: none;
|
|
||||||
}
|
}
|
||||||
`}
|
trigger="click"
|
||||||
>
|
placement={'bottomLeft'}
|
||||||
<div style={{ minHeight: 30, padding: '0 8px' }}>
|
overlayClassName={css`
|
||||||
<FormContext.Provider value={form}>
|
padding-top: 0;
|
||||||
<RecursionField schema={schema} name={fieldSchema.name} />
|
.ant-popover-arrow {
|
||||||
</FormContext.Provider>
|
display: none;
|
||||||
</div>
|
}
|
||||||
</StablePopover>
|
`}
|
||||||
</FormItem>
|
>
|
||||||
);
|
<div style={{ minHeight: 30, padding: '0 8px' }}>
|
||||||
});
|
<FormContext.Provider value={form}>
|
||||||
|
<RecursionField schema={schema} name={fieldSchema.name} />
|
||||||
|
</FormContext.Provider>
|
||||||
|
</div>
|
||||||
|
</StablePopover>
|
||||||
|
</FormItem>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
{ displayName: 'Editable' },
|
||||||
|
);
|
||||||
|
|
||||||
export const QuickEdit = observer((props) => {
|
export const QuickEdit = observer(
|
||||||
const field = useField<Field>();
|
(props) => {
|
||||||
const { getCollectionJoinField } = useCollectionManager_deprecated();
|
const field = useField<Field>();
|
||||||
const fieldSchema = useFieldSchema();
|
const { getCollectionJoinField } = useCollectionManager_deprecated();
|
||||||
const collectionField = getCollectionJoinField(fieldSchema['x-collection-field']);
|
const fieldSchema = useFieldSchema();
|
||||||
if (!collectionField) {
|
const collectionField = getCollectionJoinField(fieldSchema['x-collection-field']);
|
||||||
return null;
|
if (!collectionField) {
|
||||||
}
|
return null;
|
||||||
return field.editable ? <Editable {...props} /> : <FormItem {...props} style={{ padding: '0 8px' }} />;
|
}
|
||||||
});
|
return field.editable ? <Editable {...props} /> : <FormItem {...props} style={{ padding: '0 8px' }} />;
|
||||||
|
},
|
||||||
|
{ displayName: 'QuickEdit' },
|
||||||
|
);
|
||||||
|
@ -16,6 +16,7 @@ import { useFieldNames } from './useFieldNames';
|
|||||||
import { getLabelFormatValue, useLabelUiSchema } from './util';
|
import { getLabelFormatValue, useLabelUiSchema } from './util';
|
||||||
|
|
||||||
export const RecordPickerContext = createContext(null);
|
export const RecordPickerContext = createContext(null);
|
||||||
|
RecordPickerContext.displayName = 'RecordPickerContext';
|
||||||
|
|
||||||
function flatData(data) {
|
function flatData(data) {
|
||||||
const newArr = [];
|
const newArr = [];
|
||||||
|
@ -13,6 +13,7 @@ import {
|
|||||||
import React, { createContext, useContext, useState } from 'react';
|
import React, { createContext, useContext, useState } from 'react';
|
||||||
|
|
||||||
const DataSourceContext = createContext(null);
|
const DataSourceContext = createContext(null);
|
||||||
|
DataSourceContext.displayName = 'DataSourceContext';
|
||||||
|
|
||||||
const useSelectedRowKeys = () => {
|
const useSelectedRowKeys = () => {
|
||||||
const ctx = useContext(DataSourceContext);
|
const ctx = useContext(DataSourceContext);
|
||||||
|
@ -7,6 +7,7 @@ import { RawTextArea } from './RawTextArea';
|
|||||||
import { TextArea } from './TextArea';
|
import { TextArea } from './TextArea';
|
||||||
|
|
||||||
const VariableScopeContext = createContext([]);
|
const VariableScopeContext = createContext([]);
|
||||||
|
VariableScopeContext.displayName = 'VariableScopeContext';
|
||||||
|
|
||||||
export function VariableScopeProvider({ scope = [], children }) {
|
export function VariableScopeProvider({ scope = [], children }) {
|
||||||
return <VariableScopeContext.Provider value={scope}>{children}</VariableScopeContext.Provider>;
|
return <VariableScopeContext.Provider value={scope}>{children}</VariableScopeContext.Provider>;
|
||||||
|
@ -15,3 +15,4 @@ export const XButton = forwardRef((props: ButtonProps, ref: any) => {
|
|||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
XButton.displayName = 'XButton';
|
||||||
|
@ -2,11 +2,13 @@ import { TinyColor } from '@ctrl/tinycolor';
|
|||||||
import { useDraggable, useDroppable } from '@dnd-kit/core';
|
import { useDraggable, useDroppable } from '@dnd-kit/core';
|
||||||
import { cx } from '@emotion/css';
|
import { cx } from '@emotion/css';
|
||||||
import { Schema, observer, useField, useFieldSchema } from '@formily/react';
|
import { Schema, observer, useField, useFieldSchema } from '@formily/react';
|
||||||
import React, { HTMLAttributes, createContext, useContext } from 'react';
|
import React, { HTMLAttributes, createContext, useContext, useMemo } from 'react';
|
||||||
import { useToken } from '../../antd/__builtins__';
|
import { useToken } from '../../antd/__builtins__';
|
||||||
|
|
||||||
export const DraggableContext = createContext(null);
|
export const DraggableContext = createContext(null);
|
||||||
|
DraggableContext.displayName = 'DraggableContext';
|
||||||
export const SortableContext = createContext(null);
|
export const SortableContext = createContext(null);
|
||||||
|
SortableContext.displayName = 'SortableContext';
|
||||||
|
|
||||||
export const SortableProvider = (props) => {
|
export const SortableProvider = (props) => {
|
||||||
const { id, data, children } = props;
|
const { id, data, children } = props;
|
||||||
@ -74,15 +76,17 @@ interface SortableItemProps extends HTMLAttributes<HTMLDivElement> {
|
|||||||
export const SortableItem: React.FC<SortableItemProps> = observer(
|
export const SortableItem: React.FC<SortableItemProps> = observer(
|
||||||
(props) => {
|
(props) => {
|
||||||
const { schema, id, eid, removeParentsIfNoChildren, ...others } = useSortableItemProps(props);
|
const { schema, id, eid, removeParentsIfNoChildren, ...others } = useSortableItemProps(props);
|
||||||
|
|
||||||
|
const data = useMemo(() => {
|
||||||
|
return {
|
||||||
|
insertAdjacent: 'afterEnd',
|
||||||
|
schema: schema,
|
||||||
|
removeParentsIfNoChildren: removeParentsIfNoChildren ?? true,
|
||||||
|
};
|
||||||
|
}, [schema, removeParentsIfNoChildren]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SortableProvider
|
<SortableProvider id={id} data={data}>
|
||||||
id={id}
|
|
||||||
data={{
|
|
||||||
insertAdjacent: 'afterEnd',
|
|
||||||
schema: schema,
|
|
||||||
removeParentsIfNoChildren: removeParentsIfNoChildren ?? true,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Sortable id={eid} {...others}>
|
<Sortable id={eid} {...others}>
|
||||||
{props.children}
|
{props.children}
|
||||||
</Sortable>
|
</Sortable>
|
||||||
|
@ -2,3 +2,4 @@ import { createContext } from 'react';
|
|||||||
import { ISchemaComponentContext } from './types';
|
import { ISchemaComponentContext } from './types';
|
||||||
|
|
||||||
export const SchemaComponentContext = createContext<ISchemaComponentContext>({});
|
export const SchemaComponentContext = createContext<ISchemaComponentContext>({});
|
||||||
|
SchemaComponentContext.displayName = 'SchemaComponentContext.Provider';
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { ExpressionScope, SchemaComponentsContext, SchemaOptionsContext } from '@formily/react';
|
import { ExpressionScope, SchemaComponentsContext, SchemaOptionsContext } from '@formily/react';
|
||||||
import React, { useContext } from 'react';
|
import React, { memo, useContext, useMemo } from 'react';
|
||||||
import { ISchemaComponentOptionsProps } from '../types';
|
import { ISchemaComponentOptionsProps } from '../types';
|
||||||
|
|
||||||
export const useSchemaOptionsContext = () => {
|
export const useSchemaOptionsContext = () => {
|
||||||
@ -7,16 +7,28 @@ export const useSchemaOptionsContext = () => {
|
|||||||
return options || {};
|
return options || {};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SchemaComponentOptions: React.FC<ISchemaComponentOptionsProps> = (props) => {
|
export const SchemaComponentOptions: React.FC<ISchemaComponentOptionsProps> = memo((props) => {
|
||||||
const { children } = props;
|
const { children } = props;
|
||||||
const options = useSchemaOptionsContext();
|
const options = useSchemaOptionsContext();
|
||||||
const components = { ...options.components, ...props.components };
|
const components = useMemo(() => {
|
||||||
const scope = { ...options.scope, ...props.scope };
|
return { ...options.components, ...props.components };
|
||||||
|
}, [options.components, props.components]);
|
||||||
|
|
||||||
|
const scope = useMemo(() => {
|
||||||
|
return { ...options.scope, ...props.scope };
|
||||||
|
}, [options.scope, props.scope]);
|
||||||
|
|
||||||
|
const schemaOptionsContextValue = useMemo(() => {
|
||||||
|
return { scope, components };
|
||||||
|
}, [scope, components]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SchemaOptionsContext.Provider value={{ scope, components }}>
|
<SchemaOptionsContext.Provider value={schemaOptionsContextValue}>
|
||||||
<SchemaComponentsContext.Provider value={components}>
|
<SchemaComponentsContext.Provider value={components}>
|
||||||
<ExpressionScope value={scope}>{children}</ExpressionScope>
|
<ExpressionScope value={scope}>{children}</ExpressionScope>
|
||||||
</SchemaComponentsContext.Provider>
|
</SchemaComponentsContext.Provider>
|
||||||
</SchemaOptionsContext.Provider>
|
</SchemaOptionsContext.Provider>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
|
||||||
|
SchemaComponentOptions.displayName = 'SchemaComponentOptions';
|
||||||
|
@ -44,28 +44,36 @@ Schema.registerCompiler(Registry.compile);
|
|||||||
|
|
||||||
export const SchemaComponentProvider: React.FC<ISchemaComponentProvider> = (props) => {
|
export const SchemaComponentProvider: React.FC<ISchemaComponentProvider> = (props) => {
|
||||||
const { designable, onDesignableChange, components, children } = props;
|
const { designable, onDesignableChange, components, children } = props;
|
||||||
const [, setUid] = useState(uid());
|
const [uidValue, setUid] = useState(uid());
|
||||||
const [formId, setFormId] = useState(uid());
|
const [formId, setFormId] = useState(uid());
|
||||||
const form = useMemo(() => props.form || createForm(), [formId]);
|
const form = useMemo(() => props.form || createForm(), [formId]);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const scope = { ...props.scope, t, randomString };
|
const scope = useMemo(() => {
|
||||||
|
return { ...props.scope, t, randomString };
|
||||||
|
}, [props.scope, t]);
|
||||||
const [active, setActive] = useState(designable);
|
const [active, setActive] = useState(designable);
|
||||||
|
|
||||||
|
const schemaComponentContextValue = useMemo(
|
||||||
|
() => ({
|
||||||
|
scope,
|
||||||
|
components,
|
||||||
|
reset: () => setFormId(uid()),
|
||||||
|
refresh: () => {
|
||||||
|
setUid(uid());
|
||||||
|
},
|
||||||
|
designable: typeof designable === 'boolean' ? designable : active,
|
||||||
|
setDesignable: (value) => {
|
||||||
|
if (typeof designable !== 'boolean') {
|
||||||
|
setActive(value);
|
||||||
|
}
|
||||||
|
onDesignableChange?.(value);
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
[uidValue, scope, components, designable, active],
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SchemaComponentContext.Provider
|
<SchemaComponentContext.Provider value={schemaComponentContextValue}>
|
||||||
value={{
|
|
||||||
scope,
|
|
||||||
components,
|
|
||||||
reset: () => setFormId(uid()),
|
|
||||||
refresh: () => setUid(uid()),
|
|
||||||
designable: typeof designable === 'boolean' ? designable : active,
|
|
||||||
setDesignable: (value) => {
|
|
||||||
if (typeof designable !== 'boolean') {
|
|
||||||
setActive(value);
|
|
||||||
}
|
|
||||||
onDesignableChange?.(value);
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<FormProvider form={form}>
|
<FormProvider form={form}>
|
||||||
<SchemaComponentOptions inherit scope={scope} components={components}>
|
<SchemaComponentOptions inherit scope={scope} components={components}>
|
||||||
{children}
|
{children}
|
||||||
|
@ -36,3 +36,4 @@ export const AsDefaultTemplate = React.forwardRef((props: any, ref) => {
|
|||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
AsDefaultTemplate.displayName = 'AsDefaultTemplate';
|
||||||
|
@ -276,3 +276,4 @@ ArrayCollapse.Copy = React.forwardRef((props: any, ref) => {
|
|||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
(ArrayCollapse as any).Copy.displayName = 'ArrayCollapse.Copy';
|
||||||
|
@ -32,3 +32,4 @@ export const EnableLinkage = React.forwardRef((props: any, ref) => {
|
|||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
EnableLinkage.displayName = 'EnableLinkage';
|
||||||
|
@ -266,3 +266,4 @@ ArrayCollapse.Copy = React.forwardRef((props: any, ref) => {
|
|||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
(ArrayCollapse as any).Copy.displayName = 'ArrayCollapse.Copy';
|
||||||
|
@ -11,5 +11,8 @@ export interface FilterContextProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const RemoveActionContext = createContext(null);
|
export const RemoveActionContext = createContext(null);
|
||||||
|
RemoveActionContext.displayName = 'RemoveActionContext';
|
||||||
export const FilterContext = createContext<FilterContextProps>(null);
|
export const FilterContext = createContext<FilterContextProps>(null);
|
||||||
|
FilterContext.displayName = 'FilterContext';
|
||||||
export const LinkageLogicContext = createContext(null);
|
export const LinkageLogicContext = createContext(null);
|
||||||
|
LinkageLogicContext.displayName = 'LinkageLogicContext';
|
||||||
|
@ -124,6 +124,7 @@ interface SchemaSettingsContextProps<T = any> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const SchemaSettingsContext = createContext<SchemaSettingsContextProps>(null);
|
const SchemaSettingsContext = createContext<SchemaSettingsContextProps>(null);
|
||||||
|
SchemaSettingsContext.displayName = 'SchemaSettingsContext';
|
||||||
|
|
||||||
export function useSchemaSettings<T = any>() {
|
export function useSchemaSettings<T = any>() {
|
||||||
return useContext(SchemaSettingsContext) as SchemaSettingsContextProps<T>;
|
return useContext(SchemaSettingsContext) as SchemaSettingsContextProps<T>;
|
||||||
|
@ -5,6 +5,7 @@ import { useSchemaTemplateManager } from './SchemaTemplateManagerProvider';
|
|||||||
import { useTemplateBlockContext } from '../block-provider/TemplateBlockProvider';
|
import { useTemplateBlockContext } from '../block-provider/TemplateBlockProvider';
|
||||||
|
|
||||||
const BlockTemplateContext = createContext<any>({});
|
const BlockTemplateContext = createContext<any>({});
|
||||||
|
BlockTemplateContext.displayName = 'BlockTemplateContext';
|
||||||
|
|
||||||
export const useBlockTemplateContext = () => {
|
export const useBlockTemplateContext = () => {
|
||||||
return useContext(BlockTemplateContext);
|
return useContext(BlockTemplateContext);
|
||||||
|
@ -11,6 +11,7 @@ import { BlockTemplate } from './BlockTemplate';
|
|||||||
import { DEFAULT_DATA_SOURCE_KEY } from '../data-source';
|
import { DEFAULT_DATA_SOURCE_KEY } from '../data-source';
|
||||||
|
|
||||||
export const SchemaTemplateManagerContext = createContext<any>({});
|
export const SchemaTemplateManagerContext = createContext<any>({});
|
||||||
|
SchemaTemplateManagerContext.displayName = 'SchemaTemplateManagerContext';
|
||||||
|
|
||||||
export const SchemaTemplateManagerProvider: React.FC<any> = (props) => {
|
export const SchemaTemplateManagerProvider: React.FC<any> = (props) => {
|
||||||
const { templates, refresh } = props;
|
const { templates, refresh } = props;
|
||||||
|
@ -4,6 +4,7 @@ import { useRequest } from '../api-client';
|
|||||||
import { useAppSpin } from '../application/hooks/useAppSpin';
|
import { useAppSpin } from '../application/hooks/useAppSpin';
|
||||||
|
|
||||||
export const SystemSettingsContext = createContext<Result<any, any>>(null);
|
export const SystemSettingsContext = createContext<Result<any, any>>(null);
|
||||||
|
SystemSettingsContext.displayName = 'SystemSettingsContext';
|
||||||
|
|
||||||
export const useSystemSettings = () => {
|
export const useSystemSettings = () => {
|
||||||
return useContext(SystemSettingsContext);
|
return useContext(SystemSettingsContext);
|
||||||
|
@ -162,6 +162,8 @@ export const SettingsMenu: React.FC<{
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const DropdownVisibleContext = createContext(null);
|
export const DropdownVisibleContext = createContext(null);
|
||||||
|
DropdownVisibleContext.displayName = 'DropdownVisibleContext';
|
||||||
|
|
||||||
export const CurrentUser = () => {
|
export const CurrentUser = () => {
|
||||||
const [visible, setVisible] = useState(false);
|
const [visible, setVisible] = useState(false);
|
||||||
const { token } = useToken();
|
const { token } = useToken();
|
||||||
|
@ -6,6 +6,7 @@ import { useAppSpin } from '../application/hooks/useAppSpin';
|
|||||||
import { useCompile } from '../schema-component';
|
import { useCompile } from '../schema-component';
|
||||||
|
|
||||||
export const CurrentUserContext = createContext<ReturnTypeOfUseRequest>(null);
|
export const CurrentUserContext = createContext<ReturnTypeOfUseRequest>(null);
|
||||||
|
CurrentUserContext.displayName = 'CurrentUserContext';
|
||||||
|
|
||||||
export const useCurrentUserContext = () => {
|
export const useCurrentUserContext = () => {
|
||||||
return useContext(CurrentUserContext);
|
return useContext(CurrentUserContext);
|
||||||
|
@ -24,6 +24,7 @@ interface OptionsOfAddMenuItem {
|
|||||||
type Item = ItemType & { _options?: OptionsOfAddMenuItem };
|
type Item = ItemType & { _options?: OptionsOfAddMenuItem };
|
||||||
|
|
||||||
const CurrentUserSettingsMenuContext = createContext<{ menuItems: React.MutableRefObject<Item[]> }>(null);
|
const CurrentUserSettingsMenuContext = createContext<{ menuItems: React.MutableRefObject<Item[]> }>(null);
|
||||||
|
CurrentUserSettingsMenuContext.displayName = 'CurrentUserSettingsMenuContext';
|
||||||
|
|
||||||
export const useCurrentUserSettingsMenu = () => {
|
export const useCurrentUserSettingsMenu = () => {
|
||||||
const { menuItems } = useContext(CurrentUserSettingsMenuContext) || {};
|
const { menuItems } = useContext(CurrentUserSettingsMenuContext) || {};
|
||||||
|
@ -16,6 +16,7 @@ import { isVariable } from './utils/isVariable';
|
|||||||
import { uniq } from './utils/uniq';
|
import { uniq } from './utils/uniq';
|
||||||
|
|
||||||
export const VariablesContext = createContext<VariablesContextType>(null);
|
export const VariablesContext = createContext<VariablesContextType>(null);
|
||||||
|
VariablesContext.displayName = 'VariablesContext';
|
||||||
|
|
||||||
const variableToCollectionName = {};
|
const variableToCollectionName = {};
|
||||||
|
|
||||||
|
@ -6,3 +6,4 @@ export const RolesManagerContext = createContext<{
|
|||||||
}>({
|
}>({
|
||||||
role: null,
|
role: null,
|
||||||
} as any);
|
} as any);
|
||||||
|
RolesManagerContext.displayName = 'RolesManagerContext';
|
||||||
|
@ -3,6 +3,7 @@ import { Spin } from 'antd';
|
|||||||
import React, { createContext, useContext } from 'react';
|
import React, { createContext, useContext } from 'react';
|
||||||
|
|
||||||
const AvailableActionsContext = createContext([]);
|
const AvailableActionsContext = createContext([]);
|
||||||
|
AvailableActionsContext.displayName = 'AvailableActionsContext';
|
||||||
|
|
||||||
export const AvailableActionsProvider: React.FC = (props) => {
|
export const AvailableActionsProvider: React.FC = (props) => {
|
||||||
const { data, loading } = useRequest<{
|
const { data, loading } = useRequest<{
|
||||||
|
@ -3,6 +3,7 @@ import { Spin } from 'antd';
|
|||||||
import React, { createContext, useContext } from 'react';
|
import React, { createContext, useContext } from 'react';
|
||||||
|
|
||||||
const MenuItemsContext = createContext(null);
|
const MenuItemsContext = createContext(null);
|
||||||
|
MenuItemsContext.displayName = 'MenuItemsContext';
|
||||||
|
|
||||||
export const toItems = (properties = {}) => {
|
export const toItems = (properties = {}) => {
|
||||||
const items = [];
|
const items = [];
|
||||||
|
@ -28,6 +28,7 @@ const toActionMap = (arr: any[]) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const RoleResourceCollectionContext = createContext<any>({});
|
export const RoleResourceCollectionContext = createContext<any>({});
|
||||||
|
RoleResourceCollectionContext.displayName = 'RoleResourceCollectionContext';
|
||||||
|
|
||||||
export const RolesResourcesActions = connect((props) => {
|
export const RolesResourcesActions = connect((props) => {
|
||||||
const { styles } = useStyles();
|
const { styles } = useStyles();
|
||||||
|
@ -4,6 +4,7 @@ import { FormProvider, SchemaComponent } from '@nocobase/client';
|
|||||||
import { scopesSchema } from '../schemas/scopes';
|
import { scopesSchema } from '../schemas/scopes';
|
||||||
|
|
||||||
const RolesResourcesScopesSelectedRowKeysContext = createContext(null);
|
const RolesResourcesScopesSelectedRowKeysContext = createContext(null);
|
||||||
|
RolesResourcesScopesSelectedRowKeysContext.displayName = 'RolesResourcesScopesSelectedRowKeysContext';
|
||||||
|
|
||||||
const RolesResourcesScopesSelectedRowKeysProvider: React.FC = (props) => {
|
const RolesResourcesScopesSelectedRowKeysProvider: React.FC = (props) => {
|
||||||
const [keys, setKeys] = useState([]);
|
const [keys, setKeys] = useState([]);
|
||||||
|
@ -103,6 +103,7 @@ const Value = observer(
|
|||||||
);
|
);
|
||||||
|
|
||||||
const IsAssociationBlock = createContext(null);
|
const IsAssociationBlock = createContext(null);
|
||||||
|
IsAssociationBlock.displayName = 'IsAssociationBlock';
|
||||||
|
|
||||||
export const AuditLogs: any = () => {
|
export const AuditLogs: any = () => {
|
||||||
const isAssoc = useContext(IsAssociationBlock);
|
const isAssoc = useContext(IsAssociationBlock);
|
||||||
|
@ -12,6 +12,7 @@ export type Authenticator = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const AuthenticatorsContext = createContext<Authenticator[]>([]);
|
export const AuthenticatorsContext = createContext<Authenticator[]>([]);
|
||||||
|
AuthenticatorsContext.displayName = 'AuthenticatorsContext';
|
||||||
|
|
||||||
export const useAuthenticator = (name: string) => {
|
export const useAuthenticator = (name: string) => {
|
||||||
const authenticators = useContext(AuthenticatorsContext);
|
const authenticators = useContext(AuthenticatorsContext);
|
||||||
|
@ -11,6 +11,7 @@ export const SignupPageContext = createContext<{
|
|||||||
}>;
|
}>;
|
||||||
};
|
};
|
||||||
}>({});
|
}>({});
|
||||||
|
SignupPageContext.displayName = 'SignupPageContext';
|
||||||
|
|
||||||
export const SignupPageProvider: React.FC<{
|
export const SignupPageProvider: React.FC<{
|
||||||
authType: string;
|
authType: string;
|
||||||
|
@ -34,9 +34,12 @@ export const useAdminSettingsForm = (authType: string) => {
|
|||||||
return auth?.components?.AdminSettingsForm;
|
return auth?.components?.AdminSettingsForm;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Options = observer(() => {
|
export const Options = observer(
|
||||||
const form = useForm();
|
() => {
|
||||||
const record = useRecord();
|
const form = useForm();
|
||||||
const Component = useAdminSettingsForm(form.values.authType || record.authType);
|
const record = useRecord();
|
||||||
return Component ? <Component /> : null;
|
const Component = useAdminSettingsForm(form.values.authType || record.authType);
|
||||||
});
|
return Component ? <Component /> : null;
|
||||||
|
},
|
||||||
|
{ displayName: 'Options' },
|
||||||
|
);
|
||||||
|
@ -3,6 +3,7 @@ import { createContext, useContext } from 'react';
|
|||||||
export const AuthTypeContext = createContext<{
|
export const AuthTypeContext = createContext<{
|
||||||
type: string;
|
type: string;
|
||||||
}>({ type: '' });
|
}>({ type: '' });
|
||||||
|
AuthTypeContext.displayName = 'AuthTypeContext';
|
||||||
|
|
||||||
export const AuthTypesContext = createContext<{
|
export const AuthTypesContext = createContext<{
|
||||||
types: {
|
types: {
|
||||||
@ -11,6 +12,7 @@ export const AuthTypesContext = createContext<{
|
|||||||
value: string;
|
value: string;
|
||||||
}[];
|
}[];
|
||||||
}>({ types: [] });
|
}>({ types: [] });
|
||||||
|
AuthTypesContext.displayName = 'AuthTypesContext';
|
||||||
|
|
||||||
export const useAuthTypes = () => {
|
export const useAuthTypes = () => {
|
||||||
const { types } = useContext(AuthTypesContext);
|
const { types } = useContext(AuthTypesContext);
|
||||||
|
@ -2,8 +2,11 @@ import { createContext, useContext } from 'react';
|
|||||||
import type { ToolbarProps } from './types';
|
import type { ToolbarProps } from './types';
|
||||||
|
|
||||||
export const CalendarToolbarContext = createContext<ToolbarProps>(null);
|
export const CalendarToolbarContext = createContext<ToolbarProps>(null);
|
||||||
|
CalendarToolbarContext.displayName = 'CalendarToolbarContext';
|
||||||
export const CalendarContext = createContext(null);
|
export const CalendarContext = createContext(null);
|
||||||
|
CalendarContext.displayName = 'CalendarContext';
|
||||||
export const DeleteEventContext = createContext(null);
|
export const DeleteEventContext = createContext(null);
|
||||||
|
DeleteEventContext.displayName = 'DeleteEventContext';
|
||||||
|
|
||||||
export const useDeleteEvent = () => {
|
export const useDeleteEvent = () => {
|
||||||
return useContext(DeleteEventContext);
|
return useContext(DeleteEventContext);
|
||||||
|
@ -5,6 +5,7 @@ import _ from 'lodash';
|
|||||||
import React, { createContext, useContext, useEffect, useMemo } from 'react';
|
import React, { createContext, useContext, useEffect, useMemo } from 'react';
|
||||||
|
|
||||||
export const CalendarBlockContext = createContext<any>({});
|
export const CalendarBlockContext = createContext<any>({});
|
||||||
|
CalendarBlockContext.displayName = 'CalendarBlockContext';
|
||||||
|
|
||||||
const InternalCalendarBlockProvider = (props) => {
|
const InternalCalendarBlockProvider = (props) => {
|
||||||
const { fieldNames, showLunar } = props;
|
const { fieldNames, showLunar } = props;
|
||||||
|
@ -7,6 +7,7 @@ export const ChartQueryMetadataContext = createContext({
|
|||||||
refresh: () => {},
|
refresh: () => {},
|
||||||
data: [] as any[],
|
data: [] as any[],
|
||||||
});
|
});
|
||||||
|
ChartQueryMetadataContext.displayName = 'ChartQueryMetadataContext';
|
||||||
|
|
||||||
export const ChartQueryMetadataProvider: React.FC = (props) => {
|
export const ChartQueryMetadataProvider: React.FC = (props) => {
|
||||||
const api = useAPIClient();
|
const api = useAPIClient();
|
||||||
|
@ -3,6 +3,7 @@ import React, { FC, useState, createContext } from 'react';
|
|||||||
import * as hooks from './hooks';
|
import * as hooks from './hooks';
|
||||||
|
|
||||||
export const DataSourceContext = createContext(null);
|
export const DataSourceContext = createContext(null);
|
||||||
|
DataSourceContext.displayName = 'DataSourceContext';
|
||||||
|
|
||||||
export const DatabaseConnectionProvider: FC = (props) => {
|
export const DatabaseConnectionProvider: FC = (props) => {
|
||||||
const [dataSource, setDataSource] = useState(null);
|
const [dataSource, setDataSource] = useState(null);
|
||||||
|
@ -33,6 +33,7 @@ const RemoteCollectionContext = createContext<{
|
|||||||
refreshRM: Function;
|
refreshRM: Function;
|
||||||
titleField: string;
|
titleField: string;
|
||||||
}>({ refreshRM: () => {}, titleField: null, targetCollection: null });
|
}>({ refreshRM: () => {}, titleField: null, targetCollection: null });
|
||||||
|
RemoteCollectionContext.displayName = 'RemoteCollectionContext';
|
||||||
export const useRemoteCollectionContext = () => {
|
export const useRemoteCollectionContext = () => {
|
||||||
return useContext(RemoteCollectionContext);
|
return useContext(RemoteCollectionContext);
|
||||||
};
|
};
|
||||||
|
@ -4,38 +4,41 @@ import { debounce } from 'lodash';
|
|||||||
import React, { useState, useMemo, useEffect } from 'react';
|
import React, { useState, useMemo, useEffect } from 'react';
|
||||||
import { useRecord } from '@nocobase/client';
|
import { useRecord } from '@nocobase/client';
|
||||||
|
|
||||||
export const FieldTitleInput = observer((props: any) => {
|
export const FieldTitleInput = observer(
|
||||||
const { value, handleFieldChange } = props;
|
(props: any) => {
|
||||||
const record = useRecord();
|
const { value, handleFieldChange } = props;
|
||||||
const [titleValue, setTitleValue] = useState(value);
|
const record = useRecord();
|
||||||
// 实时更新
|
const [titleValue, setTitleValue] = useState(value);
|
||||||
const handleRealTimeChange = (newValue: string) => {
|
// 实时更新
|
||||||
setTitleValue(newValue);
|
const handleRealTimeChange = (newValue: string) => {
|
||||||
};
|
setTitleValue(newValue);
|
||||||
|
};
|
||||||
|
|
||||||
// 防抖操作
|
// 防抖操作
|
||||||
const debouncedHandleFieldChange = useMemo(() => {
|
const debouncedHandleFieldChange = useMemo(() => {
|
||||||
return debounce((newTitle: string) => {
|
return debounce((newTitle: string) => {
|
||||||
handleFieldChange(
|
handleFieldChange(
|
||||||
{
|
{
|
||||||
uiSchema: {
|
uiSchema: {
|
||||||
...record?.uiSchema,
|
...record?.uiSchema,
|
||||||
title: newTitle,
|
title: newTitle,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
record.name,
|
||||||
record.name,
|
);
|
||||||
);
|
}, 1000);
|
||||||
}, 1000);
|
}, [handleFieldChange, record]);
|
||||||
}, [handleFieldChange, record]);
|
|
||||||
|
|
||||||
// 统一处理函数,实时更新+防抖
|
// 统一处理函数,实时更新+防抖
|
||||||
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
const newValue = e.target.value;
|
const newValue = e.target.value;
|
||||||
handleRealTimeChange(newValue);
|
handleRealTimeChange(newValue);
|
||||||
debouncedHandleFieldChange(newValue);
|
debouncedHandleFieldChange(newValue);
|
||||||
};
|
};
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setTitleValue(value);
|
setTitleValue(value);
|
||||||
}, [value]);
|
}, [value]);
|
||||||
return <Input value={titleValue} onChange={handleChange} />;
|
return <Input value={titleValue} onChange={handleChange} />;
|
||||||
});
|
},
|
||||||
|
{ displayName: 'FieldTitleInput' },
|
||||||
|
);
|
||||||
|
@ -11,6 +11,7 @@ import { dataSourceSchema } from './schemas/dataSourceTable';
|
|||||||
import { PermissionProvider } from './PermisionProvider';
|
import { PermissionProvider } from './PermisionProvider';
|
||||||
|
|
||||||
const AvailableActionsContext = createContext([]);
|
const AvailableActionsContext = createContext([]);
|
||||||
|
AvailableActionsContext.displayName = 'AvailableActionsContext';
|
||||||
|
|
||||||
const AvailableActionsProver: React.FC = (props) => {
|
const AvailableActionsProver: React.FC = (props) => {
|
||||||
const { data, loading } = useRequest<{
|
const { data, loading } = useRequest<{
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user