mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-05-05 21:49:25 +08:00
fix(kanban): unable to open popup (#6535)
* fix: handle potential errors when retrieving card schema in Kanban * fix(kanban): unable to open popup * fix(Link): cannot use 'current user' variable * fix(PagePopups): improve schema fetching and cloning logic for popups * fix(Kanban): clicking cards repeatedly opens multiple popups
This commit is contained in:
parent
27c2538d40
commit
c80fbc3063
@ -48,6 +48,7 @@ interface INocoBaseRecursionFieldProps extends IRecursionFieldProps {
|
|||||||
* Whether to use Formily Field class - performance will be reduced but provides better compatibility with Formily
|
* Whether to use Formily Field class - performance will be reduced but provides better compatibility with Formily
|
||||||
*/
|
*/
|
||||||
isUseFormilyField?: boolean;
|
isUseFormilyField?: boolean;
|
||||||
|
parentSchema?: Schema;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CollectionFieldUISchemaContext = React.createContext<CollectionFieldOptions>({});
|
const CollectionFieldUISchemaContext = React.createContext<CollectionFieldOptions>({});
|
||||||
@ -266,6 +267,7 @@ export const NocoBaseRecursionField: ReactFC<INocoBaseRecursionFieldProps> = Rea
|
|||||||
values,
|
values,
|
||||||
isUseFormilyField = true,
|
isUseFormilyField = true,
|
||||||
uiSchema,
|
uiSchema,
|
||||||
|
parentSchema,
|
||||||
} = props;
|
} = props;
|
||||||
const basePath = useBasePath(props);
|
const basePath = useBasePath(props);
|
||||||
const newFieldSchemaRef = useRef(null);
|
const newFieldSchemaRef = useRef(null);
|
||||||
@ -279,6 +281,14 @@ export const NocoBaseRecursionField: ReactFC<INocoBaseRecursionFieldProps> = Rea
|
|||||||
|
|
||||||
const fieldSchema: Schema = newFieldSchemaRef.current || oldFieldSchema;
|
const fieldSchema: Schema = newFieldSchemaRef.current || oldFieldSchema;
|
||||||
|
|
||||||
|
// Establish connection with the Schema tree
|
||||||
|
if (!fieldSchema.parent && parentSchema) {
|
||||||
|
fieldSchema.parent = parentSchema;
|
||||||
|
if (!fieldSchema.parent?.properties?.[fieldSchema.name] && fieldSchema.name) {
|
||||||
|
_.set(fieldSchema.parent, `properties.${fieldSchema.name}`, fieldSchema);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const refresh = useCallback(() => {
|
const refresh = useCallback(() => {
|
||||||
const parent = fieldSchema.parent;
|
const parent = fieldSchema.parent;
|
||||||
newFieldSchemaRef.current = new Schema(fieldSchema.toJSON(), parent);
|
newFieldSchemaRef.current = new Schema(fieldSchema.toJSON(), parent);
|
||||||
|
@ -273,7 +273,8 @@ const InternalPagePopups = (props: { paramsList?: PopupParams[] }) => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
const schemas = await Promise.all(waitList);
|
const schemas = await Promise.all(waitList);
|
||||||
const clonedSchemas = schemas.map((schema, index) => {
|
const clonedSchemas = await Promise.all(
|
||||||
|
schemas.map(async (schema, index) => {
|
||||||
if (_.isEmpty(schema)) {
|
if (_.isEmpty(schema)) {
|
||||||
return get404Schema();
|
return get404Schema();
|
||||||
}
|
}
|
||||||
@ -284,6 +285,16 @@ const InternalPagePopups = (props: { paramsList?: PopupParams[] }) => {
|
|||||||
const popupSchema = findSchemaByUid(params.puid, fieldSchema?.root);
|
const popupSchema = findSchemaByUid(params.puid, fieldSchema?.root);
|
||||||
if (popupSchema) {
|
if (popupSchema) {
|
||||||
savePopupSchemaToSchema(_.omit(popupSchema, 'parent'), schema);
|
savePopupSchemaToSchema(_.omit(popupSchema, 'parent'), schema);
|
||||||
|
} else {
|
||||||
|
// 当本地找不到 popupSchema 时,通过接口请求 puid 对应的 schema
|
||||||
|
try {
|
||||||
|
const remoteSchema = await requestSchema(params.puid);
|
||||||
|
if (remoteSchema) {
|
||||||
|
savePopupSchemaToSchema(remoteSchema, schema);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to fetch schema for puid:', params.puid, error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -297,7 +308,8 @@ const InternalPagePopups = (props: { paramsList?: PopupParams[] }) => {
|
|||||||
result['x-read-pretty'] = true;
|
result['x-read-pretty'] = true;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
});
|
}),
|
||||||
|
);
|
||||||
popupPropsRef.current = clonedSchemas.map((schema, index, items) => {
|
popupPropsRef.current = clonedSchemas.map((schema, index, items) => {
|
||||||
const schemaContext = getPopupContextFromActionOrAssociationFieldSchema(schema);
|
const schemaContext = getPopupContextFromActionOrAssociationFieldSchema(schema);
|
||||||
let hidden = false;
|
let hidden = false;
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { createForm } from '@formily/core';
|
import { createForm } from '@formily/core';
|
||||||
import { Schema } from '@formily/react';
|
import { Schema, useFieldSchema } from '@formily/react';
|
||||||
import { Spin } from 'antd';
|
import { Spin } from 'antd';
|
||||||
import React, { memo, useMemo } from 'react';
|
import React, { memo, useMemo } from 'react';
|
||||||
import { useRemoteCollectionManagerLoading } from '../../collection-manager/CollectionManagerProvider';
|
import { useRemoteCollectionManagerLoading } from '../../collection-manager/CollectionManagerProvider';
|
||||||
@ -62,6 +62,7 @@ const RequestSchemaComponent: React.FC<RemoteSchemaComponentProps> = (props) =>
|
|||||||
});
|
});
|
||||||
const NotFoundComponent = useComponent(NotFoundPage);
|
const NotFoundComponent = useComponent(NotFoundPage);
|
||||||
const collectionManagerLoading = useRemoteCollectionManagerLoading();
|
const collectionManagerLoading = useRemoteCollectionManagerLoading();
|
||||||
|
const parentSchema = useFieldSchema();
|
||||||
|
|
||||||
if (collectionManagerLoading || loading || hidden) {
|
if (collectionManagerLoading || loading || hidden) {
|
||||||
return <Spin style={{ width: '100%', marginTop: 20 }} delay={LOADING_DELAY} />;
|
return <Spin style={{ width: '100%', marginTop: 20 }} delay={LOADING_DELAY} />;
|
||||||
@ -73,10 +74,20 @@ const RequestSchemaComponent: React.FC<RemoteSchemaComponentProps> = (props) =>
|
|||||||
}
|
}
|
||||||
|
|
||||||
return noForm ? (
|
return noForm ? (
|
||||||
<SchemaComponent components={components} scope={scope} schema={schemaTransform(schema || {})} />
|
<SchemaComponent
|
||||||
|
components={components}
|
||||||
|
scope={scope}
|
||||||
|
schema={schemaTransform(schema || {})}
|
||||||
|
parentSchema={parentSchema}
|
||||||
|
/>
|
||||||
) : (
|
) : (
|
||||||
<FormProvider form={form}>
|
<FormProvider form={form}>
|
||||||
<SchemaComponent components={components} scope={scope} schema={schemaTransform(schema || {})} />
|
<SchemaComponent
|
||||||
|
components={components}
|
||||||
|
scope={scope}
|
||||||
|
schema={schemaTransform(schema || {})}
|
||||||
|
parentSchema={parentSchema}
|
||||||
|
/>
|
||||||
</FormProvider>
|
</FormProvider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -28,6 +28,7 @@ function toSchema(schema?: any) {
|
|||||||
properties: {
|
properties: {
|
||||||
[schema.name]: schema,
|
[schema.name]: schema,
|
||||||
},
|
},
|
||||||
|
name: `p_${schema.name}`,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return new Schema(schema);
|
return new Schema(schema);
|
||||||
@ -52,8 +53,9 @@ interface DistributedProps {
|
|||||||
*/
|
*/
|
||||||
export const SchemaComponentOnChangeContext = createContext<SchemaComponentOnChange>({ onChange: _.noop });
|
export const SchemaComponentOnChangeContext = createContext<SchemaComponentOnChange>({ onChange: _.noop });
|
||||||
|
|
||||||
const RecursionSchemaComponent = memo((props: ISchemaFieldProps & SchemaComponentOnChange & DistributedProps) => {
|
const RecursionSchemaComponent = memo(
|
||||||
const { components, scope, schema: _schema, distributed, onChange: _onChange, ...others } = props;
|
(props: ISchemaFieldProps & SchemaComponentOnChange & DistributedProps & { parentSchema?: Schema }) => {
|
||||||
|
const { components, scope, schema: _schema, distributed, onChange: _onChange, parentSchema, ...others } = props;
|
||||||
const ctx = useContext(SchemaComponentContext);
|
const ctx = useContext(SchemaComponentContext);
|
||||||
const schema = useMemo(() => toSchema(_schema), [_schema]);
|
const schema = useMemo(() => toSchema(_schema), [_schema]);
|
||||||
const value = useMemo(
|
const value = useMemo(
|
||||||
@ -84,26 +86,32 @@ const RecursionSchemaComponent = memo((props: ISchemaFieldProps & SchemaComponen
|
|||||||
<SchemaComponentOnChangeContext.Provider value={onChangeValue}>
|
<SchemaComponentOnChangeContext.Provider value={onChangeValue}>
|
||||||
<SchemaComponentContext.Provider value={value}>
|
<SchemaComponentContext.Provider value={value}>
|
||||||
<SchemaComponentOptions inherit components={components} scope={scope}>
|
<SchemaComponentOptions inherit components={components} scope={scope}>
|
||||||
<NocoBaseRecursionField {...others} schema={schema} isUseFormilyField />
|
<NocoBaseRecursionField {...others} schema={schema} isUseFormilyField parentSchema={parentSchema} />
|
||||||
</SchemaComponentOptions>
|
</SchemaComponentOptions>
|
||||||
</SchemaComponentContext.Provider>
|
</SchemaComponentContext.Provider>
|
||||||
</SchemaComponentOnChangeContext.Provider>
|
</SchemaComponentOnChangeContext.Provider>
|
||||||
);
|
);
|
||||||
});
|
},
|
||||||
|
);
|
||||||
|
|
||||||
RecursionSchemaComponent.displayName = 'RecursionSchemaComponent';
|
RecursionSchemaComponent.displayName = 'RecursionSchemaComponent';
|
||||||
|
|
||||||
const MemoizedSchemaComponent = memo((props: ISchemaFieldProps & SchemaComponentOnChange & DistributedProps) => {
|
const MemoizedSchemaComponent = memo(
|
||||||
const { schema, ...others } = props;
|
(props: ISchemaFieldProps & SchemaComponentOnChange & DistributedProps & { parentSchema?: Schema }) => {
|
||||||
|
const { schema, parentSchema, ...others } = props;
|
||||||
const s = useMemoizedSchema(schema);
|
const s = useMemoizedSchema(schema);
|
||||||
return <RecursionSchemaComponent {...others} schema={s} />;
|
return <RecursionSchemaComponent {...others} schema={s} parentSchema={parentSchema} />;
|
||||||
});
|
},
|
||||||
|
);
|
||||||
|
|
||||||
MemoizedSchemaComponent.displayName = 'MemoizedSchemaComponent';
|
MemoizedSchemaComponent.displayName = 'MemoizedSchemaComponent';
|
||||||
|
|
||||||
export const SchemaComponent = memo(
|
export const SchemaComponent = memo(
|
||||||
(
|
(
|
||||||
props: (ISchemaFieldProps | IRecursionFieldProps) & { memoized?: boolean } & SchemaComponentOnChange &
|
props: (ISchemaFieldProps | IRecursionFieldProps) & {
|
||||||
|
memoized?: boolean;
|
||||||
|
parentSchema?: Schema;
|
||||||
|
} & SchemaComponentOnChange &
|
||||||
DistributedProps,
|
DistributedProps,
|
||||||
) => {
|
) => {
|
||||||
const { memoized, ...others } = props;
|
const { memoized, ...others } = props;
|
||||||
|
@ -135,6 +135,7 @@ export const KanbanCard: any = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
<PopupContextProvider>
|
||||||
<Card onClick={handleCardClick} bordered={false} hoverable style={cardStyle} className={cardCss}>
|
<Card onClick={handleCardClick} bordered={false} hoverable style={cardStyle} className={cardCss}>
|
||||||
<DndContext onDragStart={onDragStart} onDragEnd={onDragEnd}>
|
<DndContext onDragStart={onDragStart} onDragEnd={onDragEnd}>
|
||||||
<FormLayout
|
<FormLayout
|
||||||
@ -149,6 +150,7 @@ export const KanbanCard: any = () => {
|
|||||||
</FormLayout>
|
</FormLayout>
|
||||||
</DndContext>
|
</DndContext>
|
||||||
</Card>
|
</Card>
|
||||||
|
</PopupContextProvider>
|
||||||
<PopupContextProvider visible={visible} setVisible={setVisible}>
|
<PopupContextProvider visible={visible} setVisible={setVisible}>
|
||||||
<VariablePopupRecordProvider recordData={recordData} collection={collection}>
|
<VariablePopupRecordProvider recordData={recordData} collection={collection}>
|
||||||
<MemorizedRecursionField schema={wrappedPopupSchema} />
|
<MemorizedRecursionField schema={wrappedPopupSchema} />
|
||||||
@ -163,8 +165,12 @@ function getPopupSchemaFromParent(fieldSchema: Schema) {
|
|||||||
return fieldSchema.parent.properties.cardViewer.properties.drawer;
|
return fieldSchema.parent.properties.cardViewer.properties.drawer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
const cardSchema = findSchemaByUid(fieldSchema['x-uid'], fieldSchema.root);
|
const cardSchema = findSchemaByUid(fieldSchema['x-uid'], fieldSchema.root);
|
||||||
return cardSchema.parent.properties.cardViewer.properties.drawer;
|
return cardSchema.parent.properties.cardViewer.properties.drawer;
|
||||||
|
} catch (e) {
|
||||||
|
console.warn(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function findSchemaByUid(uid: string, rootSchema: Schema, resultRef: { value: Schema } = { value: null }) {
|
function findSchemaByUid(uid: string, rootSchema: Schema, resultRef: { value: Schema } = { value: null }) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user